获取连接表ID匹配或是ID列表子集的记录[重复]

Posted

技术标签:

【中文标题】获取连接表ID匹配或是ID列表子集的记录[重复]【英文标题】:Get records where join table ids matches or is a subset of a list of ids [duplicate] 【发布时间】:2015-03-10 21:44:13 【问题描述】:

我有一个名为 variants 的表,它通过名为 option_values_variants 的表以多对多关系连接到另一个名为 option_values 的表 em>。

我想提取所有 variants,它们在连接的 option_values 表中具有特定的 id 子集。这更容易用一个例子来演示:

表格数据:

变体

id |      name
--------------
 1 | Tennant
 2 | Smith
 3 | Eccleston
 4 | Hurt

option_values

id | name
---------
80 | blue
81 | red
82 | green
83 | 64 gb
84 | 128 gb
85 | 256 gb
86 | short
87 | long

option_values_variants

variant_id | option_value_id
----------------------------
         1 | 80
         1 | 85
         1 | 86
         2 | 82
         2 | 85
         2 | 87
         3 | 80
         3 | 84
         3 | 86
         4 | 81
         4 | 83
         4 | 86

在此示例中,我想获取所有具有选项值“blue”和“short”的变体,特别是(因此选项值 id 为 80 和 86)。

预期结果应该是变体“Tennant”和“Eccleston”,因为这些变体同时具有“blue”和“short”,尽管它们各有一个不同的选项值。 “Hurt”有“short”但没有“blue”,所以应该排除他,“Smith”两者都没有。

在形成这个查询方面,无论是在 Rails 上下文中,还是在普通 SQL 中,我似乎都有些脑残。我似乎无法弄清楚如何指定“只有当连接表的 id 匹配或者是目标参数列表的子集时才应该进行连接”。这是我目前的尝试:

@product.variants.joins(:option_values).where(option_values: id: [80, 86]).uniq

产生 SQL 查询:

SELECT DISTINCT `variants`.* FROM `variants` 
INNER JOIN `option_values_variants` ON `option_values_variants`.`variant_id` = `variants`.`id` 
INNER JOIN `option_values` ON `option_values`.`id` = `option_values_variants`.`option_value_id` 
WHERE `variants`.`product_id` = 32 AND `option_values`.`id` IN (80, 86)

由于查询正在执行WHERE ... IN (),因此它不会产生所需的结果。使用上面的示例,我会返回“Tennant”、“Eccleston”和“Hurt”,但是“Hurt”不应该属于,因为它不包含选项值“blue”(或选项值 id 80)。

如何选择连接表行匹配的记录或者是给定 id 列表的子集?

另外,这可能是上述脑阻滞的结果,但我承认我可能没有很好地解释这一点。如果我没有任何意义,请告诉我

【问题讨论】:

GROUP BY something HAVING COUNT([DISTINCT] something) = n [其中 n 是 IN() 中的项目数] @Strawberry 你是绝对正确的。完美运行。感谢您的帮助! 【参考方案1】:

您可以使用group by 并使用having count(distinct option_values.id) = 2 指定结果具有两个选项值

   SELECT
        v.id,
        v.name
    FROM variants v
        INNER JOIN option_values_variants ov
            ON ov.variant_id = v.id 
        INNER JOIN option_values o
            ON o.id = ov.option_value_id 
    WHERE v.product_id = 32
        AND o.id IN (80, 86)
    GROUP BY
        v.id,
        v.name
    HAVING COUNT(DISTINCT o.id) = 2

【讨论】:

这绝对是 100% 的正确答案。我知道我错过了一些简单的东西。感谢您的帮助。 我的荣幸。真的。我是个书呆子,我觉得这些东西很有趣...... :)

以上是关于获取连接表ID匹配或是ID列表子集的记录[重复]的主要内容,如果未能解决你的问题,请参考以下文章

选择不同的...内部连接与选择...其中 id in (...)

更正SQL“JOIN”以从主列表创建子集 - 一个表中的id字段到另一个表中的id和标题#VB / C#

在R中,获取数据框的子集,其中列中的值包含在列表中[重复]

查询匹配列表 SQL Server 中的所有记录

在同一个sql连接中获取2个不同的记录行

如何通过聚合连接mongoDB中的两个表并需要根据匹配获取结果[重复]