首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查询具有多到多关系的记录,其基础是它是否具有某些相应的记录。

查询具有多到多关系的记录,其基础是它是否具有某些相应的记录。
EN

Stack Overflow用户
提问于 2014-01-14 18:15:43
回答 1查看 58关注 0票数 0

这个应用程序运行在Rails 4和Ruby 2上。

我有两个模型,键和和弦,有一个多到多的关系through: Keychords.

Keychord有两个字段:key_idchord_id

我想要运行一个查询,返回在给定的和弦数组中包含每个和弦的所有键。

例如。

key1与IDs:[1, 2, 3, 4]的和弦相关。

key2与IDs:[1, 3, 4, 6]的和弦相关。

key3与IDs:[2, 3, 5, 6]的和弦相关。

key4与IDs:[1, 3, 4, 5]的和弦相关。

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

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

我正在使用的Psuedo代码,但不知道如何实际编写:

代码语言:javascript
复制
Key.with(:chords, [2,3])

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-14 18:38:16

尝试:

代码语言:javascript
复制
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])

最新情况-解释:

这其实相当麻烦,但到目前为止,我还没有看到更好的解决办法。例如,假设我们有桌子:

代码语言:javascript
复制
#Table A   |   #Table B
  id       |     id         a_id     key_id
---------------------------------------------------   
  1        |     1            1        2
  2        |     2            3        3
  3        |     3            3        2
  4        |     4            4        1
  5        |     5            2        3
           |     6            4        2

我们正在寻找与key_ids 2和3相关的A元素。

第一步是使用关联表执行联接。作为联接的结果,查询将为第二个表中有n个相关行的记录返回n行。它看起来是这样的:

代码语言:javascript
复制
 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方法完成的。结果:

代码语言:javascript
复制
 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对其进行分组。与分组一起,我们将添加with语句,该语句将计数b.key_id的所有不同值,并拒绝那些具有小于初始ids列表的组。这确保返回的记录拥有所有提供的密钥。

代码语言:javascript
复制
  a.id | COUNT(DISTINCT b.key_id)
-----------------
  1    |    1    
  2    |    1  
  3    |    2      # The only result
  4    |    1
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21120927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档