MySQL两表日期展示及BETWEEN筛选:左连接数据缺失求解
解决MySQL跨表日期查询的显示问题
你的问题核心是LEFT JOIN仅以tbl_date_a为主表,导致仅存在于tbl_date_b的日期无法被检索到,同时原查询的WHERE子句逻辑也有错误,以下是具体修正方案:
原查询的两个问题
- LEFT JOIN的局限性:LEFT JOIN只会保留左表(
tbl_date_a)的所有记录,右表(tbl_date_b)中不存在匹配的记录会被过滤,所以仅在tbl_date_b里的2022-09-08不会显示。 - WHERE子句逻辑错误:
t1.DateA OR t2.DateB BETWEEN '2022-09-06' AND '2022-09-08'实际执行逻辑是“t1.DateA不为空 或者t2.DateB在区间内”,不符合你“任意一个日期在区间内”的需求,正确写法应为t1.DateA BETWEEN '2022-09-06' AND '2022-09-08' OR t2.DateB BETWEEN '2022-09-06' AND '2022-09-08'。
修正后的查询语句
由于MySQL不支持直接的FULL OUTER JOIN,我们可以通过UNION合并左右连接的结果,确保所有区间内的日期都被覆盖:
-- 先获取tbl_date_a中符合条件的日期及对应tbl_date_b的匹配项 SELECT t1.DateA, t2.DateB FROM tbl_date_a t1 LEFT JOIN (SELECT DISTINCT DateB FROM tbl_date_b) t2 ON t1.DateA = t2.DateB WHERE t1.DateA BETWEEN '2022-09-06' AND '2022-09-08' UNION -- 再获取tbl_date_b中符合条件但tbl_date_a中没有的日期 SELECT NULL AS DateA, t2.DateB FROM tbl_date_b t2 LEFT JOIN tbl_date_a t1 ON t2.DateB = t1.DateA WHERE t2.DateB BETWEEN '2022-09-06' AND '2022-09-08' AND t1.DateA IS NULL ORDER BY COALESCE(DateA, DateB);
或者用更简洁的CTE方式(MySQL 8.0+支持):
WITH all_target_dates AS ( -- 收集所有区间内存在于任一表的日期 SELECT DateA AS date_val FROM tbl_date_a WHERE DateA BETWEEN '2022-09-06' AND '2022-09-08' UNION SELECT DateB AS date_val FROM tbl_date_b WHERE DateB BETWEEN '2022-09-06' AND '2022-09-08' ) SELECT ad.date_val AS DateA, tb.DateB FROM all_target_dates ad LEFT JOIN tbl_date_a ta ON ad.date_val = ta.DateA LEFT JOIN (SELECT DISTINCT DateB FROM tbl_date_b) tb ON ad.date_val = tb.DateB ORDER BY ad.date_val;
说明
UNION会自动去重,确保同一日期不会重复显示COALESCE(DateA, DateB)用于将NULL的DateA替换为DateB,保证排序逻辑正确- 子查询中用
DISTINCT替代GROUP BY,更直观地实现日期去重
内容的提问来源于stack exchange,提问作者IT Projects
相关产品推荐
相关产品推荐

