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

如何在SQL中返回指定时间范围的所有行,即使指定条件不存在

解决SQL中缺失月份的显示问题

嗨,作为SQL新手遇到这种缺失数据显示的问题很正常!你的核心需求是要强制展示201801到201804的所有月份,哪怕某个月份没有code='001'的记录,对吧?

原查询的问题

你原来的查询是直接过滤code='001'后再筛选月份,这会导致没有该code记录的月份直接被排除在结果之外。要实现你的期望,我们需要先生成目标范围内的所有月份列表,再和原表做左连接,这样就能保留所有月份,再对缺失的记录填充默认值。

解决方案(分数据库版本)

下面提供两种常用的实现方式,你可以根据自己使用的数据库选择:

方式一:递归CTE生成月份列表(适用于MySQL 8.0+、SQL Server、PostgreSQL)

递归CTE可以灵活生成连续的月份范围,适合范围较大的情况:

WITH target_months AS (
    SELECT '201801' AS YM
    UNION ALL
    SELECT 
        CASE 
            WHEN RIGHT(YM,2) = '12' THEN CONCAT(LEFT(YM,4)+1, '01')
            ELSE CONCAT(LEFT(YM,4), LPAD(RIGHT(YM,2)+1, 2, '0'))
        END AS YM
    FROM target_months
    WHERE YM < '201804'
)
SELECT 
    tm.YM,
    COALESCE(p.code, '0') AS code,
    COALESCE(p.hour, 0) AS hour
FROM target_months tm
LEFT JOIN pod11 p ON tm.YM = p.YM AND p.code = '001'
ORDER BY tm.YM;

代码说明:

  • target_months 递归生成了201801到201804的所有月份;
  • 左连接原表pod11时,把code='001'放在连接条件里(而非WHERE子句),确保不过滤掉没有匹配的月份;
  • COALESCE函数会把NULL值替换成你需要的默认值(code替换为'0',hour替换为0)。

方式二:数字表生成月份列表(适用于MySQL 5.x等不支持CTE的版本)

如果你的数据库不支持递归CTE,可以用简单的数字子查询生成目标月份:

SELECT 
    ym_list.YM,
    COALESCE(p.code, '0') AS code,
    COALESCE(p.hour, 0) AS hour
FROM (
    SELECT 
        CONCAT('2018', LPAD(n, 2, '0')) AS YM
    FROM (
        SELECT 1 AS n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
    ) nums
) ym_list
LEFT JOIN pod11 p ON ym_list.YM = p.YM AND p.code = '001'
ORDER BY ym_list.YM;

代码说明:

  • 内层子查询生成1-4的数字,通过CONCAT和LPAD拼接成201801到201804的月份;
  • 后续的左连接和默认值填充逻辑和方式一一致。

执行以上任意一种查询,就能得到你期望的结果:

YM    code hour
----------------
201801 001 112
201802 001 64
201803 0   0
201804 0   0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:32:44