单个查询可获取过去7天的个别天数,包括0天的天数

时间:2013-04-12 08:38:35

标签: mysql sql

SELECT DATE_FORMAT(createdTimestamp, "%D %b") AS date,
       COUNT(id) AS COUNT
FROM registration
WHERE createdTimestamp BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE()
GROUP BY DATE(createdTimestamp)

它会显示类似

的内容
14th Feb - 10
15th Feb - 12
16th Feb - 4
17th Feb - 4
18th Feb - 10
19th Feb - 12
20th Feb - 9

但是如果有一天没有注册它会跳过这一天,我怎么用mysql查询显示为0?

14th Feb - 10
16th Feb - 4
17th Feb - 4
20th Feb - 9

查询可以将其显示为如下所示

14th Feb - 10
15th Feb - 0
16th Feb - 4
17th Feb - 4
18th Feb - 0
19th Feb - 0
20th Feb - 9

4 个答案:

答案 0 :(得分:3)

类似的东西(you need to generate date table):

<强> SQLFIDDLEExample

select a.Date,
       COALESCE((SELECT cnt
        FROM Table1 t1
        WHERE t1.date = a.Date), 0) as COUNT
from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
where a.Date between '2013-02-01' and '2013-03-01' 
ORDER BY a.Date

结果:

|                            DATE | COUNT |
-------------------------------------------
| February, 14 2013 00:00:00+0000 |    10 |
| February, 15 2013 00:00:00+0000 |     0 |
| February, 16 2013 00:00:00+0000 |     4 |
| February, 17 2013 00:00:00+0000 |     4 |
| February, 18 2013 00:00:00+0000 |     0 |
| February, 19 2013 00:00:00+0000 |     0 |
| February, 20 2013 00:00:00+0000 |     9 |

您的查询应如下所示:

select DATE_FORMAT(a.Date, "%D %b") AS date,
       COALESCE((SELECT COUNT(id)
                 FROM registration
                 WHERE createdTimestamp = a.Date), 0) as COUNT
from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
where a.Date between DATE_SUB(CURDATE(), INTERVAL 7 DAY) and CURDATE()
ORDER BY a.Date

答案 1 :(得分:2)

此查询创建一个包含7个数字(从0到6)的序列,并使用curdate和序列号之间的日差来提取所需的数据:

SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL t.DAY DAY), "%D %b") AS date,
   COUNT(r.id) AS COUNT
FROM
  (SELECT 0 AS 'day'
       UNION ALL SELECT 1
   UNION ALL SELECT 2
   UNION ALL SELECT 3
   UNION ALL SELECT 4
   UNION ALL SELECT 5
   UNION ALL SELECT 6) t
LEFT OUTER JOIN registration r ON DATE_SUB(CURDATE(), INTERVAL t.DAY DAY) = r.createdTimestamp
GROUP BY t.DAY

这是指向sqlfiddle

的链接

答案 2 :(得分:1)

您当前的查询无法使用。查询不能按不存在的内容进行分组。您需要生成缺少的数据。

选择要作为表格选择的日期列表,然后通过日期和分组按照生成的日期表中的数据列对此数据进行OUTER JOIN。

编辑:您可以生成一个日期表,以这种方式启动(例如2天):

select * from (select subdate(current_date,0)) a union (select subdate(current_date,1) b);

答案 3 :(得分:1)

要获取日期范围,您可以采用整数表(从0到9)并将其与自身连接以获得所需的一系列数字,然后使用DATE_SUB从中获取日期范围。

然后LEFT OUTER JOIN与当前表格相关联,以获取每个日期的计数。

如下所示: -

SELECT DATE_FORMAT(aDate, "%D %b") AS fmtdate, COUNT(registration.id) AS COUNT
FROM (SELECT DATE_SUB(CURDATE(), INTERVAL a.i + b.i*10 DAY) AS aDate
FROM integers a, integers b
WHERE (a.i + b.i*10) <= 7) CountRange
LEFT OUTER JOIN registration
ON aDate = DATE(FROM_UNIXTIME(createdTimestamp))
GROUP BY aDate
ORDER BY aDate

(请注意,这将处理长达99天的时间 - 我只是为了演示如何扩展范围而对整数进行连接)

编辑 - 上面的代码正在使用FROM_UNIXTIME,因为我假设您的时间戳存储为unix时间戳。如果我的假设不正确,很容易删除该函数调用