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
相关产品推荐
相关产品推荐

