听起来你在寻找EXTRACT:
M.where(%q{
array[extract(month from d)::int, extract(day from d)::int] between array[?, ?] and array[?, ?]
}, lower_month, lower_day, upper_month, upper_day)
其中M 是您的模型,bday 是生日列,上下变量保存月份和日期边界。你也可以使用INTERSECT:
M.find_by_sql([%q{
select * from ms where array[? ,?] <= array[extract(month from bday)::int, extract(day from bday)::int]
intersect
select * from ms where array[?, ?] >= array[extract(month from bday)::int, extract(day from bday)::int]
}, lower_month, lower_day, upper_month, upper_day])
另一个版本将使用to_char:
M.where(
"to_char(bday, 'MM') || to_char(bday, 'DD') between ? and ?",
'%2.2d%2.2d' % [lower_month, lower_day],
'%2.2d%2.2d' % [upper_month, upper_day]
)
你也可以用一大堆丑陋的 CASE 语句得到相同的结果(这样你就只考虑月份边界处的日期),但交叉点 (IMO) 更清晰且更易于阅读.使用 (PostgreSQL) 数组,您可以将月/日对作为单个单位而不是单独进行比较。