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

MySQL查询指定城市日期区间数据时,如何因某日期无数据返回空结果?

解决方法:确保日期区间内每天都有数据才返回结果

看起来你需要的是只有当指定日期区间的每一天都存在LA的记录时,才返回对应的数据;只要区间内有一天没有LA数据,就返回空结果。原来的查询只是筛选出区间内已有的LA数据,但没有做完整性校验,所以会返回存在的2行。

下面提供两种常见的实现思路,你可以根据自己使用的数据库选择合适的方法:


方法一:通过日期计数对比验证

这种方法的核心是:计算目标区间的总天数,再统计LA在该区间内的不同日期数量,只有当两者相等时,才返回数据。

SELECT t.*
FROM your_table t
WHERE t.date BETWEEN '2019-09-13' AND '2019-09-15'
  AND t.city = 'LA'
-- 子查询统计LA在区间内的有效日期数,和总天数对比
AND (
  SELECT COUNT(DISTINCT date)
  FROM your_table
  WHERE date BETWEEN '2019-09-13' AND '2019-09-15'
    AND city = 'LA'
) = DATEDIFF('2019-09-15', '2019-09-13') + 1;

解释:

  • DATEDIFF('2019-09-15', '2019-09-13') + 1 计算出区间的总天数(13到15是3天)。
  • 子查询统计LA在该区间内有数据的不同日期数量,如果这个数量等于总天数,说明每天都有LA的记录,此时才会返回原查询的结果;否则整个WHERE条件不成立,返回空。

方法二:生成日期序列并检查缺失

如果你的数据库支持递归CTE(比如MySQL 8.0+、PostgreSQL、SQL Server),可以先生成区间内的所有日期,再检查是否有日期没有对应的LA记录。

以MySQL为例:

-- 生成目标区间内的所有日期
WITH date_range AS (
  SELECT '2019-09-13' AS date
  UNION ALL
  SELECT DATE_ADD(date, INTERVAL 1 DAY)
  FROM date_range
  WHERE date < '2019-09-15'
)
SELECT t.*
FROM your_table t
WHERE t.date BETWEEN '2019-09-13' AND '2019-09-15'
  AND t.city = 'LA'
-- 检查是否存在没有LA数据的日期,没有的话才返回结果
AND NOT EXISTS (
  SELECT 1
  FROM date_range dr
  LEFT JOIN your_table t2 ON dr.date = t2.date AND t2.city = 'LA'
  WHERE t2.date IS NULL
);

解释:

  • CTE date_range 生成了2019-09-13到2019-09-15的所有日期。
  • NOT EXISTS 子查询会检查是否有日期没有匹配到LA的记录,如果有缺失,这个子查询返回true,NOT EXISTS就变成false,整个查询返回空;如果所有日期都有LA数据,就返回对应的行。

如果你的数据库是PostgreSQL,可以用generate_series来简化日期序列的生成:

SELECT t.*
FROM your_table t
WHERE t.date BETWEEN '2019-09-13' AND '2019-09-15'
  AND t.city = 'LA'
AND NOT EXISTS (
  SELECT 1
  FROM generate_series('2019-09-13'::date, '2019-09-15'::date, '1 day') dr(date)
  LEFT JOIN your_table t2 ON dr.date = t2.date AND t2.city = 'LA'
  WHERE t2.date IS NULL
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:08:03