如何通过SQL查询根据不同日期获取对应的季节?
日期转季节的SQL验证与正确实现
需求说明
现有日期列数据:
Date ------- 01-Jun-2005 06-Sep-2008 25-Dec-2010 30-Mar-2003 31-Aug-2001 17-Oct-2002 20-May-2007 15-Apr-2006 18-Feb-2007 16-Jan-2002
季节划分规则:
- 春季:3月20日-6月21日
- 夏季:6月21日-9月22日
- 秋季:9月22日-12月22日
- 冬季:12月22日-次年3月20日
你提供的期望输出中存在两处笔误:06-Sep-2008按规则应属夏季,20-May-2007按规则应属春季,修正后的合理期望输出应为:
Date Season ------- ------- 01-Jun-2005 Summer 06-Sep-2008 Summer 25-Dec-2010 Winter 30-Mar-2003 Spring 31-Aug-2001 Summer 17-Oct-2002 Autumn 20-May-2007 Spring 15-Apr-2006 Spring 18-Feb-2007 Winter 16-Jan-2002 Winter
原SQL的问题分析
你编写的SQL存在以下3个核心问题:
- 日期格式错误:
'22-Dec-%%'这种通配符写法不符合SQL日期比较逻辑,数据库无法解析模糊匹配的日期范围,BETWEEN需要明确的合法日期值。 - 缺失秋季分支:CASE语句未处理9月22日-12月21日的秋季区间,该范围的日期会落入ELSE分支被错误归类为Winter。
- 跨年度冬季未正确处理:冬季是跨年度区间(12月22日到次年3月20日),原写法的
BETWEEN无法覆盖跨年场景,会导致12月22日-12月31日的日期无法被识别为冬季。
正确的SQL实现
通用思路
提取日期的月日部分(格式化为MMDD的数字字符串),通过判断月日区间划分季节,避开年份干扰,自然处理跨年的冬季场景。
Oracle 版本
SELECT "Date" AS Dates, CASE -- 冬季:12月22日 - 次年3月20日 WHEN TO_CHAR("Date", 'MMDD') BETWEEN '1222' AND '1231' OR TO_CHAR("Date", 'MMDD') BETWEEN '0101' AND '0320' THEN 'Winter' -- 春季:3月21日 - 6月21日 WHEN TO_CHAR("Date", 'MMDD') BETWEEN '0321' AND '0621' THEN 'Spring' -- 夏季:6月22日 - 9月22日 WHEN TO_CHAR("Date", 'MMDD') BETWEEN '0622' AND '0922' THEN 'Summer' -- 秋季:9月23日 - 12月21日 ELSE 'Autumn' END AS Season FROM T1;
MySQL 版本
SELECT `Date` AS Dates, CASE WHEN DATE_FORMAT(`Date`, '%m%d') BETWEEN '1222' AND '1231' OR DATE_FORMAT(`Date`, '%m%d') BETWEEN '0101' AND '0320' THEN 'Winter' WHEN DATE_FORMAT(`Date`, '%m%d') BETWEEN '0321' AND '0621' THEN 'Spring' WHEN DATE_FORMAT(`Date`, '%m%d') BETWEEN '0622' AND '0922' THEN 'Summer' ELSE 'Autumn' END AS Season FROM T1;
验证结果
执行上述SQL后,将得到符合季节规则的正确结果,与修正后的期望输出一致。
内容的提问来源于stack exchange,提问作者Khayyam Jafarov
相关产品推荐
相关产品推荐

