我想选择将某些内容标记为收藏的用户数,如果当前用户已“投票”,则返回。我的表看起来像这样
CREATE TABLE IF NOT EXISTS `favorites` (
`user` int(11) NOT NULL DEFAULT '0',
`content` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`user`,`content`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
说我有3行包含
INSERT INTO `favorites` (`user`, `content`) VALUES
(11, 26977),
(22, 26977),
(33, 26977);
使用此
SELECT COUNT(*), CASE
WHEN user='22'
THEN 1
ELSE 0
END as has_voted
FROM favorites WHERE content = '26977'
我希望获得has_voted=1
和COUNT(*)=3
,但
我得到has_voted=0
和COUNT(*)=3
。这是为什么?如何解决?
答案 0 :(得分:6)
这是因为您在一个SELECT
中混合了聚合和非聚合表达式。聚合表达式适用于许多行;非聚合表达式适用于单行。当您拥有COUNT(*)
时,汇总的(即CASE
)和非汇总(即SELECT
)表达式应出现在同一GROUP BY
中,这在你的情况。
您可以通过聚合第二个表达式来修复您的查询 - 即在其周围添加SUM
,如下所示:
SELECT
COUNT(*) AS FavoriteCount
, SUM(CASE WHEN user=22 THEN 1 ELSE 0 END) as has_voted
FROM favorites
WHERE content = 26977
现在两个表达式都已聚合,因此您应该得到预期的结果。
答案 1 :(得分:5)
使用SUM()
而不使用CASE
SELECT
COUNT(*),
SUM(USER = '22') AS has_voted
FROM
favorites
WHERE content = '26977'
答案 2 :(得分:2)
试试这个:
SELECT COUNT(*), MAX(USER=22) AS has_voted
FROM favorites
WHERE content = 26977;
<强>输出强>
| COUNT(*) | HAS_VOTED |
|----------|-----------|
| 3 | 1 |
答案 3 :(得分:1)
你需要总票数。
SELECT COUNT(*), SUM(CASE
WHEN user='22'
THEN 1
ELSE 0
END) as has_voted
FROM favorites WHERE content = '26977'
答案 4 :(得分:1)
您无意中在此处使用了MySQL功能:您将结果聚合为仅获得一条显示匹配数的结果记录(聚合函数COUNT)。但是,您还会在结果行中显示用户(或者更确切地说是构建在其上的表达式)(没有任何聚合函数)。所以问题是:哪个用户?另一个dbms会给你一个错误,要求你在GROUP BY中声明用户或聚合用户。 MySQL改为选择随机用户。
您要在此处执行的操作是聚合用户(或者更确切地说是聚合了您的表达式)。使用SUM汇总用户对所请求内容的所有投票:
SELECT
COUNT(*),
SUM(CASE WHEN user='22' THEN 1 ELSE 0 END) as sum_votes
FROM favorites
WHERE content = '26977';
答案 5 :(得分:1)
您忘记将CASE
语句包含在聚合函数中。在这种情况下,has_voted
将包含意外结果,因为您实际上正在执行“部分分组依据”。以下是您需要做的事情:
SELECT COUNT(*), SUM(CASE WHEN USER = 22 THEN 1 ELSE 0 END) AS has_voted
FROM favorites
WHERE content = 26977
或者:
SELECT COUNT(*), COUNT(CASE WHEN USER = 22 THEN 1 ELSE NULL END) AS has_voted
FROM favorites
WHERE content = 26977