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

如何使用Knex按月-日区间查询所有年份的生日数据

Knex跨月生日区间查询解决方案

你的现有代码逻辑只适用于同月份内的日期区间查询,当区间跨月(比如3月28日到4月3日)时,会因为同时要求「日>=28」和「日<=3」导致没有匹配结果——单个日期不可能同时满足这两个条件。

要实现跨年份的月-日区间查询,可参考以下两种解决方案:

方案一:分跨月/同月逻辑处理

const query = this.db("user_table");

// 计算起始和结束日期的月、日(确保两位格式)
const startDate = sub(new Date(), { days: 7 });
const endDate = new Date();
const monthIni = format(startDate, "MM");
const dayIni = format(startDate, "DD");
const monthEnd = format(endDate, "MM");
const dayEnd = format(endDate, "DD");

if (monthIni === monthEnd) {
  // 区间在同一个月内,直接匹配月相等且日在区间内
  query.whereRaw(
    "EXTRACT(MONTH FROM user_table.birth) = ? AND EXTRACT(DAY FROM user_table.birth) BETWEEN ? AND ?",
    [monthIni, dayIni, dayEnd]
  );
} else {
  // 区间跨月,匹配「起始月的起始日之后」或「结束月的结束日之前」
  query.where((builder) => {
    builder.whereRaw(
      "EXTRACT(MONTH FROM user_table.birth) = ? AND EXTRACT(DAY FROM user_table.birth) >= ?",
      [monthIni, dayIni]
    ).orWhereRaw(
      "EXTRACT(MONTH FROM user_table.birth) = ? AND EXTRACT(DAY FROM user_table.birth) <= ?",
      [monthEnd, dayEnd]
    );
  });
}

方案二:转换为月-日字符串比较(更简洁)

如果你的数据库支持日期格式化函数,可以直接将生日转换为MM-DD格式的字符串,再做区间比较(不同数据库对应函数不同):

  • PostgreSQL 使用 TO_CHAR(birth, 'MM-DD')
  • MySQL 使用 DATE_FORMAT(birth, '%m-%d')
  • SQL Server 使用 FORMAT(birth, 'MM-dd')

示例(以PostgreSQL为例):

const query = this.db("user_table");

const startDate = sub(new Date(), { days: 7 });
const endDate = new Date();
const startMonthDay = format(startDate, "MM-DD");
const endMonthDay = format(endDate, "MM-DD");

query.whereRaw(
  "TO_CHAR(user_table.birth, 'MM-DD') BETWEEN ? AND ?",
  [startMonthDay, endMonthDay]
);

这种方法无需判断是否跨月,字符串比较会自动处理跨月场景(比如03-28 <= 04-03逻辑成立)。

内容的提问来源于stack exchange,提问作者Ezequiel Tavares

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:33:34