【问题标题】:SELECT CASE, COUNT(*)选择案例,计数(*)
【发布时间】:2014-02-09 14:02:49
【问题描述】:

我想选择将某些内容标记为收藏的用户数量,并且如果当前用户“投票”了,也返回。我的桌子是这样的

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=1COUNT(*)=3 但是

我得到has_voted=0COUNT(*)=3。这是为什么?如何解决?

【问题讨论】:

    标签: mysql sql select max case


    【解决方案1】:

    这是因为您在单个 SELECT 中混合了聚合表达式和非聚合表达式。聚合表达式适用于多行;非聚合表达式适用于单行。当您有GROUP BY 时,聚合(即COUNT(*))和非聚合(即CASE)表达式应该出现在同一个SELECT 中,这在您的情况下没有意义。

    您可以通过聚合第二个表达式来修复您的查询 - 即在其周围添加 SUM,如下所示:

    SELECT
        COUNT(*) AS FavoriteCount
    ,   SUM(CASE WHEN user=22 THEN 1 ELSE 0 END) as has_voted
    FROM favorites
    WHERE content = 26977
    

    现在两个表达式都被聚合了,所以你应该得到预期的结果。

    【讨论】:

      【解决方案2】:

      尝试使用SUM() 和不使用CASE

      SELECT 
        COUNT(*),
        SUM(USER = '22') AS has_voted 
      FROM
        favorites 
      WHERE content = '26977' 
      

      See Fiddle Demo

      【讨论】:

        【解决方案3】:

        试试这个:

        SELECT COUNT(*), MAX(USER=22) AS has_voted
        FROM favorites 
        WHERE content = 26977;
        

        查看SQL FIDDLE DEMO

        输出

        | COUNT(*) | HAS_VOTED |
        |----------|-----------|
        |        3 |         1 |
        

        【讨论】:

        • 这是使用 MySQL 功能检索布尔表达式结果的一个很好的例子。给出的问题的一个很好的解决方案。如果您不仅给出了一个可行的解决方案,而且解释了 daker 的错误,那么您的回答会很棒。不过,我的投票是我认为的最佳解决方案。
        【解决方案4】:

        你需要总票数。

        SELECT COUNT(*), SUM(CASE
                WHEN user='22'
                   THEN 1
                   ELSE 0
           END) as has_voted
        FROM favorites WHERE content = '26977'
        

        【讨论】:

          【解决方案5】:

          您在此处无意中使用了 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';
          

          【讨论】:

            【解决方案6】:

            您忘记将 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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-11-11
              • 2015-06-10
              • 2011-06-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多