2010-03-18 7 views
0

configuration de base de données (MySQL)utilisateur soumis top 5 et trier par popularité

Table: top_fives

id, uid, first,  second, third, fourth, fifth, creation_date 
1, 1, cheese, eggs, ham,  bacon, ketchup, 2010-03-17 
2, 2, mayonaise, cheese, ketchup, eggs, bacon, 2010-03-17 

Les utilisateurs peuvent soumettre leur top 5 d'un certain sujet. Maintenant, je voudrais un résumé des cinq meilleurs classés par popularité.

Chaque colonne a sa propre valeur de point. colonne « première » est récompensé de 5 points, « deuxième » quatre points, « troisième » trois points, et ainsi de suite ...

Ainsi, dans mon exemple, il devrait être quelque chose comme ceci:

1 Cheese  (9 points = 5 + 4 -> 1 time in 'first' column and 1 time in 'second' column) 
2 Eggs  (6 points) 
3 Mayonaise (5 points) 
4 Ketchup (4 points) 
5 Bacon  (3 points) 
6 Ham  (3 points) 

Quelle serait la solution la plus simple (PHP) pour ce genre de situation?

+0

@Bundy: Par curiosité, avez-vous essayé aussi ma requête? –

Répondre

1

La meilleure solution serait d'avoir normalisé vos données en premier lieu. Et la seule solution pratique consiste à simuler le comportement d'une base de données correctement normalisée. Certes, la solution ne doit pas impliquer de code PHP et doit être fait sur la base de données:

SELECT type, SUM(score) 
FROM 
(
(SELECT first as type, COUNT(*)*5 as score 
FROM top_fives 
GROUP BY first 
) UNION 
(SELECT second AS type, COUNT(*)*4 as score 
FROM top_fives 
GROUP BY second 
) UNION 
(SELECT third AS type, COUNT(*)*3 as score 
FROM top_fives 
GROUP BY third 
) UNION 
(SELECT fourth AS type, COUNT(*)*2 as score 
FROM top_fives 
GROUP BY fourth 
) UNION 
(SELECT fifith AS type, COUNT(*) as score 
FROM top_fives 
GROUP BY fifth 
) 
) 
GROUP By type 
ORDER BY SUM(score) DESC; 

C.

+0

Merci, cela a fait l'affaire! La table avait besoin d'un alias quand même :) – Bundy

1

La solution serait de normaliser votre table (voir ci-dessous).

Si vous ne pouvez pas, vous devriez être en mesure de le faire:

Select name, Sum(points) total_points 
From (
    Select first name, 5 points 
    From top_fives 
    Union 
    Select second name, 4 points 
    From top_fives 
    Union 
    ... 
) 
Group By name 
Order By total_points Desc 

solution Normalisée:

food 

food_id, food_name 
1  cheese 
2  eggs 
3  ham 
... 

food_rating 
------ 
uid, food_id, points 
1 1  5 
1 2  4 
1 3  3 
2 1  4 

.

Select f.food_name, Sum(r.points) total_points 
From food_rating r 
Join food f On (f.food_id = r.food_id) 
Group By food_name 
Order By total_points Desc