MySQL中Between运算符为何无法处理文本格式月份?
问题出在字符串字典序和日期逻辑顺序不匹配,以及BETWEEN的比较规则上:
字符串比较按字符ASCII码顺序执行
数据库处理字符串类型的BETWEEN时,不会把'October-21'这类文本识别成日期,只会逐个字符对比ASCII码值。比如'December-21'的首字母是D(ASCII码68),'October-21'的首字母是O(ASCII码79),所以字典序上'December-21' < 'October-21'。BETWEEN的区间判断是严格的逻辑与
BETWEEN a AND b等价于字段 >= a AND 字段 <= b。你写的BETWEEN 'October-21' AND 'December-21',相当于要求月份字符串同时满足大于等于'October-21'和小于等于'December-21'——但'October-21'本身就比'December-21'大,没有任何字符串能同时满足这两个条件,自然查不到任何记录,SUM(downloads)返回null。IN运算符不受顺序影响
IN是直接匹配给定的所有字符串,不管它们的字典序顺序,所以能正确选中'October-21'、'November-21'、'December-21'这三个月份的记录,得到正确的求和结果。
解决办法
最可靠的方式是把文本格式的月份转换成日期类型后再做区间查询,以MySQL为例:
SELECT SUM(downloads) FROM ratings WHERE STR_TO_DATE(months, '%M-%y') BETWEEN '2021-10-01' AND '2021-12-31';
其他数据库可使用对应日期转换函数:Oracle用TO_DATE(months, 'MON-YY'),SQL Server用CONVERT(DATE, months, 106),具体函数根据数据库类型调整。
内容的提问来源于stack exchange,提问作者Ashutosh bafna

