如何按年月范围筛选maintable表数据?BETWEEN语句失效问题
这问题我碰到过好多次啦——你写的monat BETWEEN 11 AND 2根本不会返回任何数据,因为BETWEEN是按连续的数值区间来匹配的,11比2大,这个区间其实是空的,数据库找不到符合条件的月份。
下面给你两种靠谱的解决方案,按需选择就行:
方案1:把年月转换成日期再筛选(直观易读)
直接把jahr和monat组合成一个日期字段,然后用BETWEEN筛选日期范围。SQL Server里可以用DATEFROMPARTS函数快速构造日期:
SELECT jahr, monat, alles FROM dbo.maintable WHERE DATEFROMPARTS(jahr, monat, 1) BETWEEN '2017-11-01' AND '2018-02-28'
如果是SQL Server 2012之前的版本,没法用DATEFROMPARTS,可以手动拼接字符串转日期:
SELECT jahr, monat, alles FROM dbo.maintable WHERE CAST(CAST(jahr AS VARCHAR(4)) + '-' + RIGHT('0' + CAST(monat AS VARCHAR(2)), 2) + '-01' AS DATE) BETWEEN '2017-11-01' AND '2018-02-28'
这种方法的好处是逻辑清晰,谁看都懂,但如果表数据量特别大,且没有针对这个构造日期的索引,查询性能可能会差一点。
方案2:用纯逻辑条件判断(性能更优)
直接针对年份和月份写逻辑分支,不用转换日期,能更好地利用jahr和monat的联合索引:
SELECT jahr, monat, alles FROM dbo.maintable WHERE -- 2017年的11月及以后 (jahr = 2017 AND monat >= 11) -- 或者2018年的2月及以前 OR (jahr = 2018 AND monat <= 2)
如果你的筛选范围更大(比如从2017年11月到2020年2月),可以扩展成通用逻辑:
SELECT jahr, monat, alles FROM dbo.maintable WHERE -- 中间年份的所有月份都符合 (jahr > 2017 AND jahr < 2020) -- 起始年的起始月及以后 OR (jahr = 2017 AND monat >= 11) -- 结束年的结束月及以前 OR (jahr = 2020 AND monat <= 2)
这种方法性能更好,因为数据库可以直接用索引过滤年份和月份,适合大数据量的场景。
额外提醒
如果你的monat字段存储的是字符串(比如'11'、'02'),记得先转换成数值类型再比较,避免字符串排序导致的错误(比如'9'会比'11'大)。
内容的提问来源于stack exchange,提问作者frank
相关产品推荐
相关产品推荐

