在SQL中

时间:2019-03-31 00:30:38

标签: mysql sql group-by

我有一张这样的桌子:

created_date  | id | status | completed_date
2019-03-20    | 1  | Open   | 
2019-03-20    | 2  | Open   | 
2019-03-19    | 3  | Comp   | 2019-03-21
2019-03-21    | 4  | Comp   | 2019-03-22
2019-03-22    | 5  | Comp   | 2019-03-22
2019-03-18    | 6  | Open   | 

我想查找所有在ID之前创建且状态为'2019-03-21'的{​​{1}}的计数,或者它们是在'Open'之前创建的,甚至有一个'2019-03-21'状态,但它们在'Comp'之后完成。

以下是我的查询:

'2019-03-21'

它给出正确的结果。也就是说,在21日,开放了4个ID。但是现在我需要最近4天的信息。我如何修改此查询来做到这一点?

输出应为:

SELECT 
    CAST(CREATED AS DATE),
    COUNT(DISTINCT id)
FROM testtable
WHERE
    (CAST(CREATED AS DATE) <= '2019-03-21' AND status = 'Open')
    OR (
        CAST(CREATED AS DATE) <= '2019-03-21' AND status='Comp' 
        AND CAST(COMPLETED AS DATE) > '2019-03-21' 
    )

请帮助!

1 个答案:

答案 0 :(得分:0)

这是一个可以正确处理您的示例数据的解决方案。它使用可在列created_date中找到的不同值生成日期列表,然后LEFT JOIN将其与表一起使用。 JOIN条件具有您所描述的逻辑。在我看来,您不需要检查记录的status,因为显然任何具有非{NULL completed_date的记录都处于状态Comp

SELECT 
    dt.created_date,
    COUNT(t.id)
FROM 
    (SELECT DISTINCT created_date FROM mytable) dt
    LEFT JOIN mytable t
        ON t.created_date <= dt.created_date 
        AND (t.completed_date IS NULL OR t.completed_date > dt.created_date)
GROUP BY dt.created_date

Demo on DB Fiddle 及其示例数据将返回:

| created_date | COUNT(t.id) |
| ------------ | ----------- |
| 2019-03-18   | 1           |
| 2019-03-19   | 2           |
| 2019-03-20   | 4           |
| 2019-03-21   | 4           |
| 2019-03-22   | 3           |