You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现日期范围查询返回每日数据行,含无记录日期?

如何在查询结果中包含无数据源的日期?

这个需求太常见啦——当我们要按日期做统计,但原始数据里缺了某些日期的记录时,核心思路就是先生成包含所有目标日期的完整序列,再和原始数据做左连接,最后聚合统计。下面分几种常用数据库给你具体实现方案:

1. MySQL(8.0+ 支持递归CTE)

MySQL没有内置的日期生成函数,我们可以用递归CTE造出目标日期范围:

WITH RECURSIVE date_range AS (
    -- 起始日期
    SELECT '2018-03-01' AS date_val
    UNION ALL
    -- 递归生成后续日期
    SELECT DATE_ADD(date_val, INTERVAL 1 DAY)
    FROM date_range
    WHERE date_val < '2018-03-03' -- 结束日期
)
SELECT 
    dr.date_val AS Date,
    -- 用COALESCE把NULL转为0
    COALESCE(SUM(t.Amount), 0) AS Total
FROM date_range dr
-- 左连接原始表,匹配日期
LEFT JOIN your_table t ON DATE(t.DateAndTime) = dr.date_val
GROUP BY dr.date_val
ORDER BY dr.date_val;

2. PostgreSQL

PostgreSQL有generate_series函数,生成日期序列更省心:

SELECT 
    dr.date_val AS Date,
    COALESCE(SUM(t.Amount), 0) AS Total
-- 直接生成从起始到结束的日期序列
FROM generate_series('2018-03-01'::date, '2018-03-03'::date, '1 day'::interval) dr(date_val)
LEFT JOIN your_table t ON DATE(t.DateAndTime) = dr.date_val
GROUP BY dr.date_val
ORDER BY dr.date_val;

3. SQL Server

用递归CTE生成日期序列,逻辑和MySQL类似:

WITH date_range AS (
    SELECT CAST('2018-03-01' AS DATE) AS date_val
    UNION ALL
    SELECT DATEADD(DAY, 1, date_val)
    FROM date_range
    WHERE date_val < CAST('2018-03-03' AS DATE)
)
SELECT 
    dr.date_val AS Date,
    -- 用ISNULL把NULL转为0
    ISNULL(SUM(t.Amount), 0) AS Total
FROM date_range dr
LEFT JOIN your_table t ON CAST(t.DateAndTime AS DATE) = dr.date_val
GROUP BY dr.date_val
ORDER BY dr.date_val
OPTION (MAXRECURSION 0); -- 如果日期范围超过100天,必须加这个参数

额外注意点

  • 记得把代码里的your_table替换成你实际的表名
  • 如果日期范围是动态的(比如统计最近30天),可以把起始/结束日期改成动态计算,比如MySQL用CURDATE() - INTERVAL 29 DAY作为起始日期
  • 要是DateAndTime字段有索引,建议用t.DateAndTime >= dr.date_val AND t.DateAndTime < dr.date_val + INTERVAL 1 DAY替代DATE()函数,避免索引失效

内容的提问来源于stack exchange,提问作者Infin8Loop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:40:32