我有一个 Rails 模型 DailyAssignment
有一个日期列,并想找到今天之后没有 DailyAssignment
的第一个日期与之相关。
例如,如果我今天有实例,明天没有实例,后天有实例,则此方法应该明天返回。
如果我要在 Ruby 中执行此操作,它会是这样的:
(Date.today..1.year.since.to_date).find do |date|
DailyAssignment.where(date: date).empty?
end
这是中等的好,因为它会在找到记录后终止迭代,但有两个问题:
- 在 Ruby 中迭代集合很慢。
- 除了某种
while
构造,我需要指定一个“结束”日期。
在 PostgreSQL 中是否有一个很好、有效的方法来做到这一点?
最佳答案
如果可以,您应该使用自定义查询来搜索您的数据库(这种搜索在数据库中要快得多)。
如果您搜索某个时间范围内的日期,您可以使用
generate_series(timestamp, timestamp, interval)
功能:
select s
from generate_series(?, ? + interval '1 year'), interval '1 day') s
left join daily_assignment on s = "date"
where "date" is null
limit 1
如果您没有真正的上限,您可以使用自连接来获取下一个空闲日期:
select coalesce(
(select c."date" + interval '1 day'
from daily_assignment c
left join daily_assignment n on n."date" = c."date" + interval '1 day'
where c."date" > ? - interval '1 day'
and n."date" is null
order by c."date"
limit 1),
? + interval '1 day'
)
? 标记表示今天的参数(您可能需要转换,具体取决于您的输入);如果愿意,您可以使用 now()
。
P.S.:请不要使用date
作为列名,它是SQL 中的保留字,与列本身无关。相反,您可以使用 created_at
、updated_at
、happens_at
等名称,甚至可以使用 at_date
。
关于ruby-on-rails - 当前日期之后没有关联记录的最早日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28309116/