【问题标题】:Trouble with SELECT CASESELECT CASE 的问题
【发布时间】:2016-05-12 14:28:39
【问题描述】:

我想从我的数据库中获取过去 31 天的一些数据。当“finalized”列为 NULL 时,我想从“today”列获取数据,但如果“finalized”列不为 NULL,我想从“finalized”列获取数据。我总是想得到最后输入的行。

表我的收入

id          INT(11) AI
date        datetime
today       decimal(4,2)    NULL
finalized   decimal(4,2)    NULL

id    date                   today    finalized
-----------------------------------------------
6     2016-02-04 04:52:00    0.39     NULL
5     2016-02-03 12:34:00    NULL     19.74
4     2016-02-03 12:33:00    15.96    NULL
3     2016-02-03 12:32:00    12.32    NULL
2     2016-02-02 15:16:00    NULL     9.16
1     2016-02-02 14:29:00    2.20     NULL

SQL

SELECT
    date,
    CASE
        WHEN finalized=NULL
            THEN today
        WHEN finalized!=NULL
            THEN finalized
        END
    AS earn
FROM MyEarnings
GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
ORDER BY date  ASC
LIMIT 0 , 31

这就是我的结局

date                   earn
---------------------------
2016-02-02 00:00:00    NULL
2016-02-03 00:00:00    NULL
2016-02-04 00:00:00    NULL

我想要得到什么

date                   earn
----------------------------
2016-02-02 00:00:00    9.16
2016-02-03 00:00:00    19.74
2016-02-04 00:00:00    0.39

编辑

我还想获取“finalized”列中所有值的每个月的摘要,其中包含每天的最大“id”。

【问题讨论】:

    标签: mysql sql select case


    【解决方案1】:

    使用最大的 id 来确定添加的最后一行(缺点:扩展了传统的 id 用法):

    SELECT DATE(me.date) date,
           COALESCE(me.finalized,me.today) earn
      FROM MyEarnings me 
      JOIN (
        SELECT MAX(id) max_id
          FROM MyEarnings
      GROUP BY DATE(date)
      ORDER BY DATE(date)
         LIMIT 31 
          ) o
        ON o.max_id = me.id 
    

    使用最大日期来确定添加的最后一行(缺点:可能的欺骗):

    SELECT DATE(me.date) date,
           COALESCE(me.finalized,me.today) earn
      FROM MyEarnings me 
      JOIN (
        SELECT MAX(date) max_date
          FROM MyEarnings
      GROUP BY DATE(date)
      ORDER BY DATE(date)
         LIMIT 31 
          ) o
        ON o.max_date = me.date
    

    【讨论】:

      【解决方案2】:

      像这样使用CASEWHEN

      CASE
              WHEN finalized IS NULL
                  THEN today
              ELSE finalized
              END
      AS earn
      

      替换查询:

      SELECT date, (CASE
                        WHEN finalized IS NULL THEN today
                        ELSE finalized
                    END;    
      ) AS earn
      FROM MyEarnings
      GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
      ORDER BY date ASC LIMIT 0,31
      

      【讨论】:

        【解决方案3】:

        您需要条件聚合,但这有点棘手。我认为这可以满足您的要求:

        SELECT DATE_FORMAT(date, '%Y-%m-%d'),
               COALESCE(MAX(finalized), MAX(today)) as earn
        FROM MyEarnings
        GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
        ORDER BY date  ASC
        LIMIT 0 , 31;
        

        这将返回today 的最大值。您可能需要最新的值。如果是这样,最简单的方法可能是GROUP_CONCAT()/SUBSTRING_INDEX()方法:

        SELECT DATE_FORMAT(date, '%Y-%m-%d'),
               COALESCE(MAX(finalized),
                        SUBSTRING_INDEX(GROUP_CONCAT(today ORDER BY date DESC), ',', 1) + 0
                       ) as earn
        FROM MyEarnings
        GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
        ORDER BY date  ASC
        LIMIT 0 , 31;
        

        为此目的将数字转换为字符串并返回有点令人讨厌。替代方法需要额外的连接或使用变量。

        【讨论】:

        • 谢谢,但这并不总是我想要的最大值,因为当我的收入最终确定时,它可能会降低。所以我需要'id'最高的行。
        • 这正是我想要做的!谢谢!
        • 一个问题,您的最后一个代码是否会给我最终确定的 MAX,而不考虑是否在稍后添加的“最终确定”中的值较低?我希望“today”列和“finalized”列都能为我提供 ID 最高的值。
        • 我还想获取“finalized”列中每个月所有值的摘要,其中包含每天的最大“id”。
        • @DavidHermansson 。 . .样本数据每天只有一个值finalized。如果可用,则查询返回此值;否则,它将返回 today 的最新值。
        【解决方案4】:

        您不能将 null 与 != 进行比较,您应该像这样使用 is null 和 is not null:

        SELECT
        date,
        CASE
            WHEN finalized is null THEN today
            ELSE finalized
            END AS earn
        FROM MyEarnings
        GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
        ORDER BY date  ASC  LIMIT 0 , 31
        

        另外,如果你的第一个条件是null,你不需要检查它是否不是null,ELSE就足够了,因为null的反面不是null

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-13
          • 1970-01-01
          相关资源
          最近更新 更多