根据日期计算/分组行,包括缺失
Posted
技术标签:
【中文标题】根据日期计算/分组行,包括缺失【英文标题】:Count/group rows based on date including missing 【发布时间】:2013-09-25 10:57:56 【问题描述】:我的数据库中有一堆表示订单的行,即
id | date
---------------------
1 | 2013-09-01
2 | 2013-09-01
3 | 2013-09-02
4 | 2013-09-04
5 | 2013-09-04
我想要显示每天的行数,包括缺失的天数,所以输出是:
2013-09-01 | 2
2013-09-02 | 1
2013-09-03 | 0
2013-09-04 | 2
我已经看到有 2 个表的示例,一个带有记录,另一个带有日期,但理想情况下我希望有一个单独的表。
我目前可以找到有记录的行,但找不到没有记录的日期。
有人知道怎么做吗?
谢谢
【问题讨论】:
如果您的日期范围不受某种限制,唯一好的选择是拥有两个表(一个带日期),因为 mysql 不支持序列。 限制显示最近7天的订单。 重复:***.com/questions/11078798/… 【参考方案1】:如果要获取最近 7 天的数据,可以通过UNION
生成伪表,例如:
SELECT
COUNT(t.id),
fixed_days.fixed_date
FROM t
RIGHT JOIN
(SELECT CURDATE() as fixed_date
UNION ALL SELECT CURDATE() - INTERVAL 1 day
UNION ALL SELECT CURDATE() - INTERVAL 2 day
UNION ALL SELECT CURDATE() - INTERVAL 3 day
UNION ALL SELECT CURDATE() - INTERVAL 4 day
UNION ALL SELECT CURDATE() - INTERVAL 5 day
UNION ALL SELECT CURDATE() - INTERVAL 6 day) AS fixed_days
ON t.`date` = `fixed_days`.`fixed_date`
GROUP BY
`fixed_days`.`fixed_date`
-看到这个fiddle demo。请注意,如果您的字段是 DATETIME
日期类型,那么您需要先申请 DATE()
:
SELECT
COUNT(t.id),
fixed_days.fixed_date
FROM t
RIGHT JOIN
(SELECT CURDATE() as fixed_date
UNION ALL SELECT CURDATE() - INTERVAL 1 day
UNION ALL SELECT CURDATE() - INTERVAL 2 day
UNION ALL SELECT CURDATE() - INTERVAL 3 day
UNION ALL SELECT CURDATE() - INTERVAL 4 day
UNION ALL SELECT CURDATE() - INTERVAL 5 day
UNION ALL SELECT CURDATE() - INTERVAL 6 day) AS fixed_days
ON DATE(t.`date`) = `fixed_days`.`fixed_date`
GROUP BY
`fixed_days`.`fixed_date`
【讨论】:
无论日期范围内是否没有行,都会为每一行返回1
如果字段是datetime
怎么办?更改 SQL 容易吗?【参考方案2】:
试试这样的东西!
SELECT
c1,
GROUP_CONCAT(c2 ORDER BY c2) AS 'C2 values'
FROM table
GROUP BY c1;
要检索在另一列 c2 中存在特定值的 c1 值列表,您需要一个指定 c2 值的 IN
子句和一个指定列表中不同项目所需数量的 HAVING
子句。 .
SELECT c1
FROM table
WHERE c2 IN (1,2,3,4)
GROUP BY c1
HAVING COUNT(DISTINCT c2)=4;
有关此相关问题的更多帮助
Counting all rows with specific columns and grouping by week
【讨论】:
【参考方案3】:使用下面的存储过程可以让你得到超过7天的结果,只要传递你想要的天数
DELIMITER $$
CREATE DEFINER=`server`@`%` PROCEDURE `test`(d INT)
BEGIN
CREATE TEMPORARY TABLE dates
(
f_day DATETIME
);
WHILE d > 0 DO
INSERT INTO dates SELECT DATE(NOW())-d;
SET d = d - 1;
END WHILE;
SELECT
IF(isnull(`id`),0,`id`),
`fixed_days`.`f_day`
FROM t
RIGHT JOIN
dates AS `fixed_days`
ON t.`date` = `fixed_days`.`f_day`
GROUP BY
`fixed_days`.`f_day`;
DROP TABLE dates;
END
【讨论】:
以上是关于根据日期计算/分组行,包括缺失的主要内容,如果未能解决你的问题,请参考以下文章