CASE将忽略重复的条目

时间:2015-09-29 02:30:52

标签: mysql sql case

我有一个存储用户投票的表,如下所示:

+----+---------+-------+---------+
| id | post_id | value | user_id |
+----+---------+-------+---------+
| 1  |   103   |   1   |    1    |
| 2  |   105   |   1   |    3    |
| 3  |   106   |   1   |    1    |
| 4  |   108   |   0   |    1    |
| 5  |   108   |   0   |    2    |
| 6  |   105   |   0   |    2    |
| 7  |   105   |   1   |    1    |
+----+---------+-------+---------+

id是投票ID,post_id是帖子ID,value是类似/不同的布尔值(1 =赞,0 =不同),user_id是选民ID。

我想得到一个列表:

  1. 所有帖子
  2. 每个帖子都像计数
  3. 每个帖子不像点数
  4. 投票用户(例如,用户1)投票的ID。所以我可以稍后更新这个值
  5. 用户提出的投票
  6. 所以我写了这个查询:

    SELECT
        post_id, 
        COUNT(
            CASE 
                WHEN value = 1 
                THEN 1 
            END
        ) AS likes, 
        COUNT(
            CASE 
                WHEN value = 0 
                THEN 1 
            END
        ) AS unlikes, 
        (CASE 
            WHEN user_id = 1    -- I choose user_id manually
            THEN id 
        END) AS vote_id, 
        (CASE 
            WHEN user_id = 1 
            THEN value 
        END) AS user_vote 
    FROM votes 
    GROUP BY post_id;
    

    我的期望是这样的:

    +---------+-------+---------+---------+-----------+
    | post_id | likes | unlikes | vote_id | user_vote |
    +---------+-------+---------+---------+-----------+
    |   103   |   1   |    0    |    1    |     1     |
    |   105   |   2   |    1    |    7    |     1     |
    |   106   |   1   |    0    |    3    |     1     |
    |   108   |   0   |    2    |    4    |     0     |
    +---------+-------+---------+---------+-----------+
    

    但这是我的结果:

    +---------+-------+---------+---------+-----------+
    | post_id | likes | unlikes | vote_id | user_vote |
    +---------+-------+---------+---------+-----------+
    |   103   |   1   |    0    |   1     |    1      |
    |   105   |   2   |    1    |   NULL  |    NULL   |
    |   106   |   1   |    0    |   3     |    1      |
    |   108   |   0   |    2    |   4     |    0      |
    +---------+-------+---------+---------+-----------+
    

    由于我的查询的最后一行(NULL),会发生GROUP BY post_id个值。如果表格中存在重复的post_id(例如,如果某个其他用户已经为该帖子投票),则CASE会忽略它并返回NULL

    我该怎么办?

1 个答案:

答案 0 :(得分:3)

您的查询存在的问题是最后两列缺少聚合。假设用户只能为帖子投票一次,您可以使用MAX()(或MIN())安全地组合这些值,因为最多只有一个匹配的行:

SELECT v.post_id, SUM(value = 1) AS likes, SUM(value = 0) AS unlikes,
       MAX(CASE WHEN user_id = 1 THEN vote_id END) AS user1_voteid,
       MAX(CASE WHEN user_id = 1 THEN value END) AS user1_vote
FROM votes v
GROUP BY v.post_id;