2009-12-10 8 views
2

J'ai une table des événements, et une autre des notes. Chaque événement peut avoir de nombreuses notes. Je dois être en mesure d'extraire les trois meilleurs événements de la base de données en évaluant, mais bien sûr, les notes doivent être moyennées, donc un événement avec une note de cinq étoiles n'est pas mieux évalué que celui avec 4 moyenne et 100 notes.Tri par classement pondéré en SQL?

Quelqu'un peut-il me guider sur la façon de créer cela en SQL?

Merci

MISE À JOUR Merci les gars Je suppose que j'aurais été plus clair avec la façon dont les choses devraient être pondérées (même si je pense que je dois penser plus sur comment exactement je veux que cela fonctionne). SQL fourni est une grande aide si

+0

Comment voulez-vous trier ces événements: 100 notes, moyenne 5, 100 évaluations, moyenne 4, 99 évaluations, moyenne 5. – Quassnoi

+0

Je suppose que je voudrais les trier dans l'ordre que vous leur avez donné. besoin de donner une idée ... – Sergio

Répondre

1

Faire des suppositions sur vos noms de colonnes et les règles de votre système de notation (ce qui est très vague), et également basée sur un arrière-plan MSSQL vous pourriez faire quelque chose comme:

select * from event where id in (
    select top 3 eventid 
    from ratings 
    group by eventid having count(*)>100 order by avg(rating) desc 
) 

vous pouvez vouloir dénormaliser cette valeur de notation en événement pour des raisons de performances si vous avez beaucoup de notes à venir dans

.
+0

Pensez que cela est proche de ce que je vais utiliser (en utilisant MS SQL Server) – Sergio

1

Puisque vous ne donnez pas de détails sur votre SGBD, il est difficile de dire exactement comment vous pouvez le faire.

Mais je pense que Google Analytics (ORACLE seulement) est ce que vous cherchez: http://www.orafaq.com/node/55

2

Votre description de l'algorithme est très vague.

Cette requête renverra des événements avec 100 notes ou moins au fond:

SELECT * 
FROM (
     SELECT e.id, AVG(r.rating) AS ar, COUNT(*) AS cnt 
     FROM event e 
     JOIN rating r 
     ON  r.event = e.id 
     GROUP BY 
       e.id 
     ) q 
ORDER BY 
     CASE WHEN cnt >= 100 THEN 0 ELSE 1 END, ar DESC 
0

C'est un peu Oracle spécifique car il utilise ROWNUM, mais essayez

SELECT * FROM 
    (SELECT EVENT_ID, EVENT_NAME FROM EVENTS) E 
INNER JOIN 
    (SELECT EVENT_ID, AVG(RATING) AS AVG_RATING 
    FROM EVENT_RATINGS 
    GROUP BY EVENT_ID) R 
ON (EVENT_ID) 
ORDER BY AVG_RATING 
WHERE ROWNUM <= 3 
+0

Cela ne sera même pas analyser. – Quassnoi

+0

Je pense qu'il a communiqué l'idée, même si la syntaxe était désactivée. Commençons par: SELECT EVENT_ID, EVENT_NAME, AVG_RATING DE CAS E INNER JOIN (SELECT EVENT_ID, AVG (note) AS AVG_RATING DE EVENT_RATINGS GROUP BY EVENT_ID) R UTILISANT (EVENT_ID) OÙ ROWNUM <= 3 COMMANDER PAR AVG_RATING Partager et en profiter. –

1

Comme d'autres l'ont dit, votre algorithme est un peu vague. Le SQL ci-dessous fera ce dont vous avez besoin, mais vous devrez remplir le ____________ avec la fonction de classement que vous voulez. Un exemple peut être fltAvgRating + LOG(intRatings).