MySQL 5.7.29:如何筛选表B落在表A多段Var='a'时间范围的记录
这是个很常见的场景——当目标匹配条件从单一区间变成多段区间时,原来的子查询写法就不适用了。这里有两种简单且高效的写法可以解决你的问题:
方法1:使用INNER JOIN关联表
这种方法直接将表B和表A中Var='a'的记录进行关联,匹配cDate落在对应时间区间内的行:
SELECT DISTINCT b.* FROM tableB b INNER JOIN tableA a ON b.cDate BETWEEN a.StartDate AND a.EndDate WHERE a.Var = 'a';
说明:
BETWEEN在这里等价于b.cDate >= a.StartDate AND b.cDate <= a.EndDate,写法更简洁;- 加上
DISTINCT是为了避免如果表B的某条记录同时落在表A的多个Var='a'区间里时,出现重复结果。如果你的业务场景中不会出现这种情况,可以去掉DISTINCT提升性能。
方法2:使用EXISTS子查询
如果你更倾向于用子查询的思路,或者担心JOIN带来的重复问题,EXISTS是个很好的选择——它会检查表B的每一行是否存在对应的表A区间满足条件:
SELECT * FROM tableB b WHERE EXISTS ( SELECT 1 FROM tableA a WHERE a.Var = 'a' AND b.cDate BETWEEN a.StartDate AND a.EndDate );
说明:
EXISTS子查询只要找到任意一个匹配的区间就会停止检查,性能通常不错;- 这种写法不会产生重复结果,因为它只是判断存在性,不会关联出多条记录。
验证结果
根据你提供的测试数据,这两种写法都会返回表B中的以下4行:
| cDate | Val1 | Val2 |
|---|---|---|
| 2020-06-19 00:25:21 | 05 | a2 |
| 2020-06-19 00:49:01 | 94 | b3 |
| 2020-06-19 01:28:01 | 56 | 2 |
| 2020-06-19 02:00:09 | 29 | 3 |
这正好是所有落在表A中Var='a'区间内的记录。
内容的提问来源于stack exchange,提问作者hsnsd
相关产品推荐
相关产品推荐

