gpt4 book ai didi

sql - 没有特定子记录的父记录的 Rails 范围

转载 作者:太空宇宙 更新时间:2023-11-03 16:14:58 25 4
gpt4 key购买 nike

我有一个父模型 Effort 有_many split_times:

class Effort
has_many :split_times
end

class SplitTime
belongs_to :effort
belongs_to :split
end

class Split
has_many :split_times
enum kind: [:start, :finish, :intermediate]
end

我需要一个范围来返回没有开始 split_time 的工作。这看起来应该是可能的,但到目前为止我还做不到。

我可以在没有 split_times 的情况下返回努力:

scope :without_split_times, -> { includes(:split_times).where(split_times: {:id => nil}) }

我可以用这个返回至少有一个 split_time 的努力:

scope :with_split_times, -> { joins(:split_times).uniq }

这是我在我想要的范围内的尝试:

scope :without_start_time, -> { joins(split_times: :split).where(split_times: {:id => nil}).where('splits.kind != ?', Split.kinds[:start]) }

但这行不通。我需要一些东西来返回所有没有 split_time 的努力,它有 kind: :start 的 split ,即使这些努力有其他的 split_times。我更喜欢 Rails 解决方案,但如果需要可以使用原始 SQL。如果重要的话,我会使用 Postgres。

最佳答案

您可以在您的标准(即 splits.kind = 'start')上进行左连接,这将包括空值(即没有匹配的行要连接)。不同之处在于 Rails 的 join 默认情况下会给你一个内部连接(两个表中都有匹配的行)但是你想要一个左连接因为你需要检查没有匹配的行右表。

根据该连接的结果,您可以按事件分组,然后计算匹配拆分的数量 - 如果它为 0,则该事件没有匹配的开始拆分!

这可能对你有用:

scope :without_start_time, -> { 
joins("LEFT JOIN split_times ON split_times.effort_id = efforts.id").
joins("LEFT OUTER JOIN splits ON split_times.split_id = splits.id " \
"AND splits.kind = 0").
group("efforts.id").
having("COUNT(splits.id) = 0")
}

关于sql - 没有特定子记录的父记录的 Rails 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47805562/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com