Sql Rails—不在特定关联旁边的联接表中的记录的范围

Sql Rails—不在特定关联旁边的联接表中的记录的范围,sql,ruby-on-rails,ruby,rails-activerecord,jointable,Sql,Ruby On Rails,Ruby,Rails Activerecord,Jointable,我在Rails应用程序中有两个模型-锦标赛和玩家通过连接表关联: class Tournament < ApplicationRecord has_many :tournament_players has_many :players, through: :tournament_players end class Player < ApplicationRecord has_many :tournament_players has_many :tourname

我在Rails应用程序中有两个模型-
锦标赛
玩家
通过连接表关联:

class Tournament < ApplicationRecord

  has_many :tournament_players
  has_many :players, through: :tournament_players

end


class Player < ApplicationRecord

  has_many :tournament_players
  has_many :tournaments, through: :tournament_players

  scope :selected, -> (tournament) { includes(:tournaments).where(tournaments: {id: tournament.id}) }

end
成功地找到所有已添加到锦标赛的玩家,将该锦标赛作为参数

我想要的是一个相反的作用域——返回所有尚未添加到给定锦标赛中的玩家。我试过了

scope :not_selected, -> (tournament) { includes(:tournaments).where.not(tournaments: {id: tournament.id}) }
但这会让很多相同的球员回归,我想是因为这些球员是作为其他比赛的一部分存在的。其SQL看起来类似于:

SELECT "players".*, "tournaments”.* FROM "players" LEFT OUTER JOIN
"tournament_players" ON "tournament_players"."player_id" =
"players"."id" LEFT OUTER JOIN "tournaments" ON "tournaments"."id" =
"tournament_players"."tournament_id" WHERE ("tournaments"."id" != $1)
ORDER BY "players"."name" ASC  [["id", 22]]
SELECT "players”.*, "tournaments”.* FROM "players" LEFT OUTER JOIN
"tournament_players" ON "tournament_players"."player_id" = 
"players"."id" LEFT OUTER JOIN "tournaments" ON "tournaments"."id" = 
"tournament_players"."tournament_id" WHERE "tournaments"."id" IS NULL 
ORDER BY "players"."name" ASC
我还尝试了关于如何使用的建议

但这似乎不起作用——它只是返回一个空数组,我想这也是因为玩家作为单独比赛的一部分存在于联接表中。其SQL看起来类似于:

SELECT "players".*, "tournaments”.* FROM "players" LEFT OUTER JOIN
"tournament_players" ON "tournament_players"."player_id" =
"players"."id" LEFT OUTER JOIN "tournaments" ON "tournaments"."id" =
"tournament_players"."tournament_id" WHERE ("tournaments"."id" != $1)
ORDER BY "players"."name" ASC  [["id", 22]]
SELECT "players”.*, "tournaments”.* FROM "players" LEFT OUTER JOIN
"tournament_players" ON "tournament_players"."player_id" = 
"players"."id" LEFT OUTER JOIN "tournaments" ON "tournaments"."id" = 
"tournament_players"."tournament_id" WHERE "tournaments"."id" IS NULL 
ORDER BY "players"."name" ASC
好的,试试这个:

includes(:tournaments).distinct.where.not(tournaments: {id: tournament.id}) 
好的,试试这个:

includes(:tournaments).distinct.where.not(tournaments: {id: tournament.id}) 

您需要做的是:

  • 与参考表进行左连接,锦标赛ID上的附加条件与您要查找未选定球员的比赛ID匹配
  • 应用WHERE子句,指示未进行联接
  • 此代码应执行以下操作:

    # player.rb
    scope :not_selected, -> (tournament) do 
      joins("LEFT JOIN tournament_players tp ON players.id = tp.player_id AND tp.tournament_id = #{tournament.id}").where(tp: {tournament_id: nil})
    end
    
    如果Rails有更好的方法来编写带有附加条件的左连接查询

    请注意:

  • 不要加入实际的关系(即锦标赛),这会显著降低查询的性能,而且这是不必要的,因为所有条件先决条件都在引用表中。此外,您感兴趣的所有行都会从tournaments表返回空数据
  • 不要使用
    eager\u load
    。除了据我所知,它不支持自定义条件之外,它还会为所有相关对象创建模型,而您不需要这些模型

  • 您需要做的是:

  • 与参考表进行左连接,锦标赛ID上的附加条件与您要查找未选定球员的比赛ID匹配
  • 应用WHERE子句,指示未进行联接
  • 此代码应执行以下操作:

    # player.rb
    scope :not_selected, -> (tournament) do 
      joins("LEFT JOIN tournament_players tp ON players.id = tp.player_id AND tp.tournament_id = #{tournament.id}").where(tp: {tournament_id: nil})
    end
    
    如果Rails有更好的方法来编写带有附加条件的左连接查询

    请注意:

  • 不要加入实际的关系(即锦标赛),这会显著降低查询的性能,而且这是不必要的,因为所有条件先决条件都在引用表中。此外,您感兴趣的所有行都会从tournaments表返回空数据
  • 不要使用
    eager\u load
    。除了据我所知,它不支持自定义条件之外,它还会为所有相关对象创建模型,而您不需要这些模型


  • 可能重复的“查看我的编辑”-从我可以看出,这些解决方案不太正确。您能显示生成的SQL吗?添加了SQL。我只是不能专心于我需要的搜索!可能重复的“查看我的编辑”-从我可以看出,这些解决方案不太正确。您能显示生成的SQL吗?添加了SQL。我只是不能专心于我需要的搜索!谢谢-但是
    :not_selected
    作用域引发此错误:
    ActiveRecord::StatementInvalid:PG::UndefinedTable:error:表“tournaments”的子句条目中缺少此项
    您可以更改吗,相反,
    includes
    put
    joins
    ?否-改为获取此错误:
    ActiveRecord::StatementInvalid:PG::GroupingError:error:column“tournaments.id”必须出现在GROUP BY子句中或在聚合函数中使用
    您可以尝试第二个选项吗?该选项只返回一个空数组。谢谢-但是
    :not_selected
    范围引发此错误:
    ActiveRecord::StatementInvalid:PG::UndefinedTable:错误:表“tournaments”的子句条目中缺少
    您可以更改吗,相反,
    includes
    put
    joins
    ?否-改为获取此错误:
    ActiveRecord::StatementInvalid:PG::GroupingError:error:column“tournaments.id”必须出现在GROUP BY子句中或用于聚合函数中
    您可以尝试第二个选项吗?该选项只返回一个空数组。谢谢!不过,它也犯了一些错误。第一个是
    玩家
    不知道传递给
    查找比赛中的非比赛
    的参数是什么。第二个问题是,
    find\u not\u in\u锦标赛
    未定义?此外,作用域缺少开头的
    do
    。放弃它-我不清楚开始时的
    find\u not\u in\u锦标赛
    方法调用的目的是什么,但如果没有它,这将非常有效。如果您将其编辑为包含缺少的
    do
    ,并删除
    find\u not\u in\u touring
    ,我会将其标记为正确答案。谢谢我从头开始写,我先写了一个方法,然后我读到你需要的是一个范围。我想我是赶时间。谢谢你的更新。谢谢你!不过,它也犯了一些错误。第一个是
    玩家
    不知道传递给
    查找比赛中的非比赛
    的参数是什么。第二个问题是,
    find\u not\u in\u锦标赛
    未定义?此外,作用域缺少开头的
    do
    。放弃它-我不清楚开始时的
    find\u not\u in\u锦标赛
    方法调用的目的是什么,但如果没有它,这将非常有效。如果您将其编辑为包含缺少的
    do
    ,并删除
    find\u not\u in\u touring
    ,我会将其标记为正确答案。谢谢我从头开始写,我先写了一个方法,然后我读到你需要的是一个范围。我想我是赶时间。谢谢你的更新。