SELECT CASE的问题

时间:2016-02-03 11:50:03

标签: mysql sql select case

我想在过去31天内从我的数据库中获取一些数据。专栏最终确定后#39;是NULL我想从列'今天'中获取数据,但是如果列已经完成'不是我想要从列中获取数据'最终确定'。我总想得到最后一行。

TABLE MyEarnings

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

修改

我还希望获得最终' -column中所有值的每个月的摘要,其中包含max' id'每一天。

4 个答案:

答案 0 :(得分:2)

像这样使用CASE WHEN

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

答案 1 :(得分:2)

你不能将null与!=进行比较,你应该使用is null并且不是这样的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,你不需要检查它是否为空,ELSE就足够了,因为null的反面不是null

答案 2 :(得分:1)

您需要条件聚合,但这有点棘手。我认为这样做你想要的:

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;

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

答案 3 :(得分:0)

使用最大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