Ruby on rails 查找在一个FK上具有一定数量匹配项的记录,具有多个:通过关联
我有很多:通过球员和球队之间的联系。这是一种多对多的关系,每支球队可以有任意数量的球员,反之亦然 我希望能够在同一外键上找到具有一定数量匹配项的记录。在这种情况下,我想找到一个团队,其中有一组特定的球员。这可以是包含的,也可以是独占的:Ruby on rails 查找在一个FK上具有一定数量匹配项的记录,具有多个:通过关联,ruby-on-rails,postgresql,performance,activerecord,Ruby On Rails,Postgresql,Performance,Activerecord,我有很多:通过球员和球队之间的联系。这是一种多对多的关系,每支球队可以有任意数量的球员,反之亦然 我希望能够在同一外键上找到具有一定数量匹配项的记录。在这种情况下,我想找到一个团队,其中有一组特定的球员。这可以是包含的,也可以是独占的: 仅由ID为11和12的球员组成的返回团队 返回拥有任意数量球员的球队,包括球员ID 11和12 或者找到只由这两名球员组成的球队 SELECT * FROM Team JOIN PlayerLink AS pl1 ON Team.id
SELECT *
FROM Team
JOIN PlayerLink AS pl1 ON Team.id = pl1.team_id
JOIN PlayerLink AS pl2 ON Team.id = pl.team_id
JOIN (
Select Team.id, COUNT(*) AS size
FROM Team
JOIN PlayerLink on Team.id = PlayerLInk.team_id
) AS t ON Team.id = t.id
WHERE pl1 = 11 AND pl2 = 12 AND t.size = 2
切中要害……
如何使用rails中的活动记录完成此操作?你能想出一个更有效的方法吗
编辑
PlayerLink.joins(“在pl2.team\u id=player\u links.team\u id=player\u links.player\u id=11和pl2.player\u id=12上作为pl2加入player\u链接”)。其中(“player\u links.player\u id=11和pl2.player\u id=12”)
没有任何合理的测试,我相信这会得到我想要的。然后,我可以遍历结果,看看它们是否包含额外的玩家,如果我愿意,可以将其排除在外
这对我来说就是效率低下。有什么更好的方法吗?首先,如果您在连接中添加了其他字段(您将其命名为PlayerLink),has\u many to非常有用,如果您没有其他信息,has\u和\u Bown\u to\u许多人将完成此工作,请参阅: 但是,对于has_many:through,请确保您遵循: 为您:
医生->团队
,患者->球员
,预约->球员链接
然后你可以做:
Team.find(<id>).players
Player.find(<id>).teams
最后,要改进查询,您应该预加载关联:
Team.includes(:players).find([1,2]).map(&:players)
(玩家视角也是如此)
由于它是Rails(配置之前的约定),您需要相应地命名您的模型(大写的类名、单数的文件名等)-因此,如果它不起作用,请仔细检查您的关联、类和文件(:player\u links
,player\u links.rb
,PlayerLink
)
我希望这有帮助
在更好地理解问题后,稍后进行编辑:
要获得包含玩家1和玩家2的团队:
PlayerTeam.joins(:team).where(player_id: [1,2]).select(:team_id).group(:team_id).having("count(team_id) > 1")
要获得只有玩家1和玩家2的团队:
PlayerLink.joins(:team).select('team_id, count(player_id)').group(:team_id).having("count(player_id) = sum(player_id in(1,2))")
对于第二个查询,请注意如何构建查询字符串,但您可能知道;) 请添加playerlink模型,并感谢您为此投入的所有时间和精力。这里的解决方案适用于找到与给定玩家相关联的团队,但当我们需要找到与2个或更多玩家相关联的团队时,就不起作用了。不过你确实给了我一个主意。我没有想到直接从join表.PlayerLink.joins(“join player\u links as pl2 ON pl2.team\u id=player\u links.team\u id”)。其中(“player\u links.player\u id=1和pl2.player\u id=3”)给出了一组结果。这是一个简单的解决方案。它的工作原理是相同的:
PlayerLink.joins(:player)。where(player\u id:[1,2],team\u id:[1,2])
(或者如果您正在寻找team,则加入team)使用join
或include
预加载关联并查询模型-您有3个可用的。最好尽可能多地使用活动记录,这样无论是谁在你(或你自己以后)之后接触项目,都会有更轻松的时间;)该代码将返回所有玩家链接的数组,其中玩家id为1或2,团队id为1或2。这将给我比我想要的更多的结果。我需要一份有玩家1和玩家2的球队名单。
Team.find([1,2]).players
Team.includes(:players).find([1,2]).map(&:players)
PlayerTeam.joins(:team).where(player_id: [1,2]).select(:team_id).group(:team_id).having("count(team_id) > 1")
PlayerLink.joins(:team).select('team_id, count(player_id)').group(:team_id).having("count(player_id) = sum(player_id in(1,2))")