2010-03-18 39 views
0

数据库设置(MySQL的)用户提交的前5名和排序按热门程度

表: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 

用户可以提交他们的前5某一主题的。现在我想根据受欢迎程度排序的前五名的总结。

每列都有自己的点值。列“第一”是奖励5分,“第二”四点,“第三”三个点,等等...

所以,在我的例子应该是这样的:

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) 

什么是这种情况下最简单的解决方案(PHP)?

+0

@Bundy:出于好奇,你试试我的查询吗? – 2010-03-18 11:25:14

回答

1

最好的解决办法是摆在首位,以已恢复正常数据。唯一可行的解​​决方案是模拟正常规范化数据库的行为。当然,解决方案不应涉及任何PHP代码,并应在数据库上进行:

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

谢谢,这个伎俩!该表需要一个别名,虽然:) – Bundy 2010-03-18 11:23:38

1

解决方案将正常化你的表(见下文)。

如果你没有,你应该能够做到可以:

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 

标准化的解决方案

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