如何在MySQL中按日期范围分组,而不跳过包含零项的日期
嗯,这可能很容易,但我似乎找不到任何解决办法 我有一个工作问题如何在MySQL中按日期范围分组,而不跳过包含零项的日期,mysql,group-by,date-range,Mysql,Group By,Date Range,嗯,这可能很容易,但我似乎找不到任何解决办法 我有一个工作问题 SELECT count(*), TIMESTAMPDIFF(DAY, buydate, NOW()) daydif FROM order_item WHERE buydate > NOW() - INTERVAL 4 DAY GROUP BY daydif ORDER BY daydif ASC 但结果是跳过了零项的日子 +----------+--------+ | count(*) | day
SELECT
count(*), TIMESTAMPDIFF(DAY, buydate, NOW()) daydif
FROM
order_item
WHERE
buydate > NOW() - INTERVAL 4 DAY
GROUP BY daydif
ORDER BY daydif ASC
但结果是跳过了零项的日子
+----------+--------+
| count(*) | daydif |
+==========+========+
| 5 | 0 |
+----------+--------+
| 9 | 1 |
+----------+--------+
| 2 | 3 |
+----------+--------+
我想得到这个结果
+----------+--------+
| count(*) | daydif |
+==========+========+
| 5 | 0 |
+----------+--------+
| 9 | 1 |
+----------+--------+
| 0 | 2 | //I want this row in the returned results
+----------+--------+
| 2 | 3 |
+----------+--------+
更新:从答案和进一步的搜索来看,我似乎被迫创建一个helper表并加入其中。令人沮丧的是,我找不到像评论中提到的MariaDB那样的序列生成函数。是否有更优雅的方式的提示?可能您没有任何物品,差异为2天。SQL无法创建某些东西,因为它不存在 您可以做的是使一个表具有一个由从0到最大的数字列表组成的长字段(在本例中为4),我们称之为tbl_diff,该字段为diff。在现有查询上左键连接tbl_diff以填补空白。请注意,我还将count()更改为仅对设置了buydate的记录进行计数
SELECT
count(buydate), TIMESTAMPDIFF(DAY, buydate, NOW()) daydif
FROM
tbl_diff
LEFT JOIN
order_item on tbl_diff.diff=TIMESTAMPDIFF(DAY, buydate, NOW())
WHERE
diff<=4
GROUP BY daydif
ORDER BY daydif ASC
正如Paul Spiegel所建议的那样,我最终使用了一些帮助表, 为了将来的参考和更好的帮助,这里是我用来生成表的代码
create table `stat_helper_calendar` (
`date` DATE NOT NULL,
PRIMARY KEY (`date`)
)
select date_add('2015-01-01', INTERVAL t3.c*1000 + t2.c*100 + t1.c*10 + t0.c DAY) as `date`
from
(select 0 c 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) t0,
(select 0 c 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) t1,
(select 0 c 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) t2,
(select 0 c 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) t3
这个是整数
CREATE TABLE `stat_helper_num` (
`num` INT NOT NULL,
PRIMARY KEY (`num`)
) SELECT (t4.c * 10000 + t3.c * 1000 + t2.c * 100 + t1.c * 10 + t0.c) AS `num` FROM
(SELECT 0 c 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) t0,
(SELECT 0 c 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) t1,
(SELECT 0 c 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) t2,
(SELECT 0 c 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) t3,
(SELECT 0 c 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) t4
您可以创建一个日历表,并使用日期将其与您的
order\u项目
表左键联接。您将了解如何创建日历表。在这种情况下,不需要日历表,只要有5个数字就足够了。在这种情况下,我同意。@PaulSpiegel,哇,这真是太聪明了!在较短范围内动态创建该表不是更好的选择吗?顺便说一句:如果您使用MariaDB,您可能想看看。刚刚测试过选择seq as daydif从seq_0_到步骤_5_1
-效果很好。buydate>NOW()-间隔4天
应该在ON子句(IMHO)中@PaulSpiegel我不确定这是否会有任何区别。实际上,对于联接条件,它是一种冗余,因为如果差值大于4天,则联接将删除记录。如果daydif为2,则将选中NULL>NOW()-INTERVAL 4 DAY
,然后过滤掉该行。这就是行动计划的问题。《明镜周刊》你说得对。然而,我完全改变了where子句。在第二种情况下,甚至不需要where子句。
CREATE TABLE `stat_helper_num` (
`num` INT NOT NULL,
PRIMARY KEY (`num`)
) SELECT (t4.c * 10000 + t3.c * 1000 + t2.c * 100 + t1.c * 10 + t0.c) AS `num` FROM
(SELECT 0 c 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) t0,
(SELECT 0 c 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) t1,
(SELECT 0 c 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) t2,
(SELECT 0 c 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) t3,
(SELECT 0 c 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) t4