Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于记录是否具有某些对应记录查询具有多对多关系的记录_Sql_Ruby On Rails_Ruby - Fatal编程技术网

Sql 基于记录是否具有某些对应记录查询具有多对多关系的记录

Sql 基于记录是否具有某些对应记录查询具有多对多关系的记录,sql,ruby-on-rails,ruby,Sql,Ruby On Rails,Ruby,此应用程序在Rails 4和Ruby 2上运行 我有两个模型,Key和Chord,它们通过:Keychords具有多对多关系 Keychord有两个字段:key\u id和chord\u id 我想运行一个查询,返回给定和弦数组中具有每个和弦的所有键 例如 键1与ID为的和弦相关:[1,2,3,4] 键2与ID为的和弦相关:[1,3,4,6] 键3与ID为的和弦相关:[2,3,5,6] 键4与ID为的和弦相关:[1,3,4,5] 如果我有一个和弦ID数组:[2,3] 我希望查询返回[key1,k

此应用程序在Rails 4和Ruby 2上运行

我有两个模型,Key和Chord,它们通过:Keychords具有多对多关系

Keychord有两个字段:
key\u id
chord\u id

我想运行一个查询,返回给定和弦数组中具有每个和弦的所有键

例如

键1与ID为的和弦相关:
[1,2,3,4]

键2与ID为的和弦相关:
[1,3,4,6]

键3与ID为的和弦相关:
[2,3,5,6]

键4与ID为的和弦相关:
[1,3,4,5]

如果我有一个和弦ID数组:
[2,3]

我希望查询返回
[key1,key3]


我想要的Psuedo代码,但不知道如何实际编写:

谢谢

试试看:

class Key < ActiveRecord::Base
  scope :with_chords, ->(chords) { joins(:keychords).where(keychords: {chord_id: chords}).group("#{table_name}.#{primary_key}").having('COUNT(DISTINCT keychords.chord) = ?', chords.size)
end

Key.with_chords([2,3])
我们正在寻找与键ID 2和3关联的元素

第一步是执行与关联表的联接。作为联接的结果,对于第二个表中有n个关联行的记录,查询将返回n行。它将如下所示:

 a.id     b.id    b.a_id    b.key_id
--------------------------------------
  1        1        1          2
  2        5        2          3   
  3        2        3          3
  3        3        3          2
  4        4        4          1
  4        6        4          2
请注意,
A
没有关联的记录根本不会返回。 下一步是过滤这些行,只取那些与我们正在寻找的(2或3)关联的行。这是通过
where
方法完成的。结果:

 a.id     b.id    b.a_id    b.key_id
--------------------------------------
  1        1        1          2
  2        5        2          3   
  3        2        3          3
  3        3        3          2
  4        6        4          2
下一步是按
a.id
对其进行分组。与分组一起,我们将添加having语句,该语句将统计
b.key\u id
的所有不同值,并拒绝包含小于初始id列表的组。这确保返回的记录具有所有提供的密钥

  a.id | COUNT(DISTINCT b.key_id)
-----------------
  1    |    1    
  2    |    1  
  3    |    2      # The only result
  4    |    1

谢谢,现在测试这个。为了澄清,我应该将其保留为“{table_name}.{primary_key}”还是
table_name
primary_key
占位符?还有,我认为你错过了一个结尾。这应该在这行的最后吗?你有没有可能愿意快速解释一下上面的每一条查询实际上是如何工作的?哇,谢谢你花时间解释这一点。非常感谢!我知道你已经很久没有回答这个问题了,但我希望你能回答我的后续问题。您将如何修改上述查询以仅返回具有精确和弦[2,3]的键,而不是在其他和弦中具有和弦[2,3]?非常感谢@jackerman09-上述声明应该已经做到了<代码>具有
语句将拒绝具有2个以上匹配项的结果。
 a.id     b.id    b.a_id    b.key_id
--------------------------------------
  1        1        1          2
  2        5        2          3   
  3        2        3          3
  3        3        3          2
  4        6        4          2
  a.id | COUNT(DISTINCT b.key_id)
-----------------
  1    |    1    
  2    |    1  
  3    |    2      # The only result
  4    |    1