You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写忽略年份、仅按日月范围筛选记录的SQL查询

SQL跨年份筛选指定月日范围实现方案

以下是不同场景下的常用实现方案,覆盖主流数据库兼容、性能优化、特殊边界处理等需求:

方案1:月日字符串拼接比较(全数据库通用兼容)

该方案不受数据库类型限制,ymd字段为DATE类型或标准YYYY-MM-DD格式字符串都可以直接使用:

  • 核心逻辑:把日期的月份、日期提取后拼接为MM-DD格式的字符串,利用MM-DD字符串的字典序和时间顺序一致的特性,直接和目标范围比较
  • 示例SQL(筛选每年5月12日到7月12日):
SELECT * FROM 你的表名
WHERE DATE_FORMAT(ymd, '%m-%d') BETWEEN '05-12' AND '07-12';

不同数据库的日期格式化函数差异:

  • PostgreSQL 替换为 TO_CHAR(ymd, 'MM-DD')
  • SQL Server 替换为 FORMAT(ymd, 'MM-dd') 或 CONVERT(VARCHAR(5), ymd, 10)
  • SQLite 替换为 STRFTIME('%m-%d', ymd)

方案2:月日数值拆分判断(性能更优)

如果数据量较大,不想每次查询都执行字符串格式化计算,可以直接拆分月份、日期做逻辑判断,搭配预先建立的月日计算字段/函数索引可以大幅提升查询性能:

SELECT * FROM 你的表名
WHERE 
  (MONTH(ymd) = 5 AND DAY(ymd) >= 12)
  OR (MONTH(ymd) = 6)
  OR (MONTH(ymd) = 7 AND DAY(ymd) <= 12);

不同数据库的月日提取函数差异:

  • PostgreSQL 替换为 EXTRACT(MONTH FROM ymd)、EXTRACT(DAY FROM ymd)
  • SQL Server 替换为 DATEPART(MONTH, ymd)、DATEPART(DAY, ymd)
  • SQLite 替换为 CAST(STRFTIME('%m', ymd) AS INTEGER)、CAST(STRFTIME('%d', ymd) AS INTEGER)

特殊场景:跨年末的月日范围处理

如果要筛选的范围跨年末,比如每年12月20日到次年1月10日,上述两种方案的BETWEEN写法会失效,调整判断逻辑即可:

-- 以通用兼容方案为例调整
SELECT * FROM 你的表名
WHERE 
  DATE_FORMAT(ymd, '%m-%d') >= '12-20'
  OR DATE_FORMAT(ymd, '%m-%d') <= '01-10';

优化建议

  • 如果这类查询是高频需求,建议新增一个mmdd计算列存储MM-DD格式内容并建立索引,查询时直接匹配该字段,性能远高于每次查询做实时函数计算
  • 如果ymd是字符串类型,务必保证存储格式为标准YYYY-MM-DD,否则所有日期函数都会失效,建议提前转成DATE类型存储

内容的提问来源于stack exchange,提问作者Vi Ha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:42:03