SQL查询:日期范围过滤及逗号分隔日期匹配问题
解决reclamations表日期范围过滤问题
表结构与示例数据
现有reclamations表结构如下:
| 列名 | 数据类型 | 描述 |
|---|---|---|
| id | INTEGER | 主键 |
| date | TEXT | 申诉原始日期 |
| remember_dates | TEXT | 逗号分隔的申诉召回日期 |
示例数据:
| id | date | remember_dates |
|---|---|---|
| 1 | 2023-05-01 | 2023-04-25, 2023-05-18 |
| 2 | 2023-05-10 | 2023-05-04, 2023-06-15 |
| 3 | 2023-06-20 | 2023-06-10, 2023-06-25 |
| 4 | 2023-07-05 | 2023-07-01, 2023-07-10 |
需求
检索满足以下任一条件的行:
date字段值在指定日期范围内(示例范围:'2023-05-01'至'2023-06-30')remember_dates中的任意日期落在该指定范围内
问题原因
直接对remember_dates字段使用BETWEEN或范围判断无效,因为数据库会把它当作完整字符串比较,而非拆分后检查每个独立日期。
解决方案
根据使用的数据库类型选择对应SQL:
1. MySQL 8.0.19+ / MariaDB 10.5+
用STRING_SPLIT拆分字符串后检查日期:
SELECT DISTINCT r.* FROM reclamations r LEFT JOIN STRING_SPLIT(r.remember_dates, ', ') s ON 1=1 WHERE r.date BETWEEN '2023-05-01' AND '2023-06-30' OR s.value BETWEEN '2023-05-01' AND '2023-06-30';
注意:如果日期分隔符是纯逗号(无空格),把
,改成,即可。
2. PostgreSQL
通过string_to_array+unnest拆分字符串:
SELECT DISTINCT r.* FROM reclamations r LEFT JOIN unnest(string_to_array(r.remember_dates, ', ')) AS s(date_val) ON 1=1 WHERE r.date BETWEEN '2023-05-01' AND '2023-06-30' OR s.date_val BETWEEN '2023-05-01' AND '2023-06-30';
3. SQL Server
使用STRING_SPLIT并显式转换日期类型:
SELECT DISTINCT r.* FROM reclamations r LEFT JOIN STRING_SPLIT(r.remember_dates, ', ') s ON 1=1 WHERE CONVERT(DATE, r.date) BETWEEN '2023-05-01' AND '2023-06-30' OR CONVERT(DATE, s.value) BETWEEN '2023-05-01' AND '2023-06-30';
4. 通用兼容方案(旧版数据库)
如果不支持字符串拆分函数,用正则匹配临时解决:
SELECT * FROM reclamations WHERE date BETWEEN '2023-05-01' AND '2023-06-30' OR remember_dates REGEXP '[[:space:]]*(2023-05-[0-9]{2}|2023-06-[0-9]{2})[[:space:]]*';
此方案需根据目标日期范围手动调整正则表达式,灵活性较差。
结果验证
按示例范围查询,应返回id为1、2、3的行:
- id=1:
date在范围内 - id=2:
remember_dates中的两个日期均在范围内 - id=3:
date和remember_dates中的日期都在范围内
内容的提问来源于stack exchange,提问作者nacer baaziz
相关产品推荐
相关产品推荐

