在开始之前,请允许我说明:
考虑2个表:
CREATE TABLE `answers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`question_id` int(11) NOT NULL DEFAULT '0',
`user_id` int(11) NOT NULL DEFAULT '0',
`text` TEXT,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `rating` (
`answer_id` int(11) NOT NULL DEFAULT '0',
`direction` varchar(10) NOT NULL DEFAULT '',
`user_id` int(11) NOT NULL DEFAULT '0',
UNIQUE KEY (`answer_id`, `user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
现在是烦人的部分。答案表是不言自明的,所以我只举几个评级行的例子
+-------------+-------------+-----------+
| answer_id | direction | user_id |
+-------------+-------------+-----------+
| 1 | up | 23 |
| 1 | down | 26 |
| 2 | up | 32 |
| 2 | up | 42 |
| 2 | up | 22 |
| 2 | down | 23 |
| 3 | up | 45 |
| 3 | up | 22 |
+-------------+-------------+-----------+
现在我要做的是选择所有answers
,每个答案的对应“向上”COUNT,“向下”COUNT,以及“向上”和“向下”COUNT之间的差异。
假设upcount
是“向上”的总数,downcount
是“向下”的总数,而score
是他们的差异,例如:
SELECT [SOMETHING?] AS `upcount`,
[SOMETHING?] AS `downcount`,
(`upcount`-`downcount`) AS `score`,
ans.* FROM answers AS ans LEFT JOIN rating AS r ON ans.id=r.answer_id
[...] ORDER BY `score`, `upcount`
当然,我强烈怀疑该解决方案会像我给出的示例一样任何。我只是想说明每条记录应该有upcount,downcount,score和所有答案字段。
非常感谢非常感谢,谢谢!
PS。我知道如果上下是2个单独的列并且有数值,我可以很容易地使用SUM()。但就像我说的,我没有创建这个表;)
答案 0 :(得分:1)
可能是一个简单的GROUP BY子句连接,但总结基于IF语句,而不是计数: -
SELECT a.id,
SUM(IF(b.direction='up', 1, 0)) AS upcount,
SUM(IF(b.direction='down', 1, 0)) AS downcount,
SUM(IF(b.direction='up', 1, -1)) AS score
FROM answers a
LEFT OUTER JOIN rating b
ON a.id = b.answer_id
GROUP BY a.id
ORDER BY score, upcount
编辑 - 避免使用SUM的IF语句的另一种可能的解决方案是加入评级表两次并使用COUNT(DISTINCT)。由于user_id对于答案是唯一的,因此我们可以计算不同的用户ID。下方是获得整体得分有点麻烦。
SELECT a.id,
COUNT(DISTINCT b1.user_id) AS upcount,
COUNT(DISTINCT b2.user_id) AS downcount,
(COUNT(DISTINCT b1.user_id) - COUNT(DISTINCT b2.user_id)) AS score
FROM answers a
LEFT OUTER JOIN rating b1
ON a.id = b1.answer_id
AND b1.direction='up'
LEFT OUTER JOIN rating b2
ON a.id = b2.answer_id
AND b2.direction='down'
GROUP BY a.id
ORDER BY score, upcount