database indeling rating script

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Roy Marijnissen

Roy Marijnissen

14/06/2011 01:06:50
Quote Anchor link
Ik heb op dit moment een rating script voor producten op een site. De indeling van de database is als volgt :

Tabel producten
id - naam - beschrijving - ratingid

Tabel rating
id - ratingid - cijfer - uitleg

Nu heb ik het script zo laten werken dat hij alle cijfers in de rating tabel optelt voor het product met ratingid en deze dan deelt door het aantal ratings. Hier komt dan een gemiddeld cijfer uit.

Dit werkt allemaal prima. Maar nu wil ik een top 5 van producten met de hoogste beoordeling maken. De bedoeling is dus eigenlijk dat hij voor alle producten (zijn er maar 20 dus valt mee !) het gemiddelde cijfer uitrekend zoals ik hierboven heb beschreven en dat hij dan de 5 hoogste scores laat zien.

Nu heb ik alleen nog geen idee hoe ik dit logisch kan aanpakken. Zou iemand mij hiermee op weg kunnen helpen ?
 
PHP hulp

PHP hulp

19/04/2024 19:02:05
 
Pieter van Linschoten

Pieter van Linschoten

14/06/2011 10:37:42
Quote Anchor link
Ik heb zoiets hier ook gemaakt:
http://www.voorspeldetrend.nl/highscores/
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT
     tabel_producten.naam
    (SUM(tabel_rating.cijfer) / COUNT(tabel_rating.*)) AS gemiddelde_score
FROM
    tabel_rating
LEFT JOIN
    tabel_producten
ON
   tabel_rating.ratingid = tabel_producten.ratingid
WHERE
    COUNT(tabel_rating.*) > 10
GROUP BY
    ratingid
ORDER BY
    gemiddelde_score DESC
LIMIT 5



PS: Dit is om het gemiddelde te berekenen over producten met minstens 10 ratings
WHERE
COUNT(tabel_rating.*) > 10
 
Arjan -

Arjan -

14/06/2011 13:07:15
Quote Anchor link
@Pieter: Alles wat je niet door een AGGREGATE functie haalt (binnen je SELECT) moet je opnemen in je GROUP BY, en andersom! Dat het in mysql meestal (!!) correct werkt (op jouw manier) is een mankement van mysql.

En volgens mij kan je beter in plaats van WHERE count(tabel_rating.*) > 10 een HAVING toevoegen aan je GROUP BY, want een AGGREGATE functie hoort normaliter niet thuis in de WHERE clausule.
Gewijzigd op 14/06/2011 13:31:07 door Arjan -
 
The Force

The Force

14/06/2011 13:41:53
Quote Anchor link
En waarom al die id's? Waarom moet de productentabel een id hebben? En waarom heeft rating een id terwijl de rating zelf ook uniek is (althans dat lijkt me)?
 
Roy Marijnissen

Roy Marijnissen

14/06/2011 13:53:03
Quote Anchor link
Zou idd niet percee nodig zijn, maar het levert ook niet echt een probleem op lijkt me ?!
 
The Force

The Force

14/06/2011 14:17:05
Quote Anchor link
Met een kleine website wellicht niet, maar het maakt je database minder logisch en minder beschrijvend. Neem eens de denkbeeldige tabellen User en UserAction. Primary key van User is username. Dan kan je bij UserAction gewoon verwijzen naar de username. Als je later de database in kijkt zie je meteen dat user "Pietje" een bepaalde actie heeft uitgevoerd (in plaats van user "81"). Het komt ook regelmatig voor dat je de primary key van de parent tabel wil gebruiken in een SELECT query. Als je alle UserActions wil weergeven en daar ook de naam bij wilt hebben moet je een join doen. Terwijl als je geen id's had gebruikt in de tabel de username al had gestaan. Ten derde moet je extra constraints gaan toevoegen als je bijvoorbeeld geen twee mensen met dezelfde username wilt hebben. Terwijl als je de username als primary key had je al klaar was. Ik durf te wedden dat er geen UNIQUE constraint staat op de productnaam ;).Ten vierde sla je gegevens op die totaal niet nodig zijn.

Dus leer je aan om het op de goede manier te doen. Kijk per tabel wat uniek is (dat kan ook een combinatie van kolommen zijn) en maak daar de primary key van. Alleen als er geen unieke (serie van) kolom(men) bestaat/bestaan dan gebruik je een id.
 
Roy Marijnissen

Roy Marijnissen

14/06/2011 14:56:45
Quote Anchor link
Aangezien het een database in opzet is heb ik het veranderd. Nu staat er in de tabel producten de zelfde info als ik in de eerste post beschreef alleen nu is id weg en is naam de belangrijkste. In de rating tabel is id ook weg en wordt vervangen door naam deze zal dan dus vaker voorkomen, deze is gelijk aan het product waarop gestemd wordt ! Hoe zou ik nu het beste de uitvoer kunnen regelen ? Ben al vollop aan het zoeken maar krijg het nog niet voor elkaar een top5 te produceren !
 
Arjan -

Arjan -

14/06/2011 17:15:59
Quote Anchor link
Relaties leggen met id's is beter, aangezien je dan nog eenvoudig benamingen in andere velden kan veranderen zonder dat daar de relatie door verbroken wordt!

Dus:
Je zal wel het veld "id" moeten behouden in je producten tabel. Alleen is de ratingid in je producten tabel overbodig, aangezien je een relatie kan leggen tussen de producten tabel en de rating tabel middels de id van het product en een veld "productid" in je rating tabel, dus zo:

Tabel producten
id - naam - beschrijving

Tabel rating
id - productid - cijfer - uitleg

De productid in de rating tabel correspondeert met het desbetreffende id van het product in de tabel producten.

Je kan dan middels onderstaande query een top 5 samen stellen (Pieter heeft je al goed op weggeholpen volgens mij):

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT
    p.id AS product_id,
    p.naam AS product_naam,
    (SUM(r.cijfer) / COUNT(r.id)) AS product_gemiddelde_rating
FROM
    producten p
LEFT JOIN
    rating r
ON
    r.productid = p.id
GROUP BY
    p.id,
    p.naam
ORDER BY
    product_gemiddelde_rating DESC
LIMIT
    5
Gewijzigd op 14/06/2011 17:18:24 door Arjan -
 
Roy Marijnissen

Roy Marijnissen

14/06/2011 17:21:31
Quote Anchor link
En hoe kan ik nu de top5 weergeven ?
 
Arjan -

Arjan -

14/06/2011 17:33:03
Quote Anchor link
Met die querie denkkkk...
 
Roy Marijnissen

Roy Marijnissen

14/06/2011 17:43:10
Quote Anchor link
Ja logisch. Bedoelde eigenlijk iets anders maar het lukt volgens mij nu wel verder :) Bedankt !
Gewijzigd op 14/06/2011 17:46:04 door Roy Marijnissen
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.