【问题标题】:SQL Select only rows where multiple relationships existSQL 仅选择存在多个关系的行
【发布时间】:2012-12-15 09:57:27
【问题描述】:

给定一个父表'parent'

╔═══════════╦══════════╗
║ PARENT_ID ║   NAME   ║
╠═══════════╬══════════╣
║         1 ║ bob      ║
║         2 ║ carol    ║
║         3 ║ stew     ║
╚═══════════╩══════════╝

以及父级和(此处未指定)属性表之间的多对多关系表“rel”

╔═══════════╦═══════════╗
║ PARENT_ID ║  PROP_ID  ║
╠═══════════╬═══════════╣
║         1 ║         5 ║
║         1 ║         1 ║
║         2 ║         5 ║
║         2 ║         4 ║
║         2 ║         1 ║
║         3 ║         1 ║
║         3 ║         3 ║
╚═══════════╩═══════════╝

如何选择所有具有所有一组指定关系的父母?例如。使用样本数据,我怎样才能找到同时拥有属性 5 和 1 的所有父母?


编辑: 同样的问题,但需要 exact 匹配: SQL Select only rows where exact multiple relationships exist

【问题讨论】:

    标签: mysql sql select


    【解决方案1】:

    将您的第一个表命名为 a,第二个表命名为 b

    SELECT parent_id FROM prop b1 
    WHERE prop_id=1 and 
    EXISTS (SELECT parent_id FROM prop b2 
            WHERE b2.parent_id=b1.parent_id AND b2.prop_id=5)
    

    【讨论】:

      【解决方案2】:

      我已将您的表格写入 CTE,如果您需要帮助以适应您的目的,请告诉我。

      ;WITH MyTable AS
      (
          SELECT   parent_id = 1
                  ,prop_id = 5    UNION ALL
          SELECT 1,1              UNION ALL
          SELECT 2,5              UNION ALL
          SELECT 2,4              UNION ALL
          SELECT 2,1              UNION ALL
          SELECT 3,1              UNION ALL
          SELECT 3,3              
      )
      ,Eval AS
      (
          SELECT   parent_id
                  ,PropEval   = SUM(CASE WHEN prop_id IN (1,5) THEN 1 ELSE 0 END)
          FROM MyTable
          GROUP BY parent_id
      )
      SELECT parent_id
      FROM Eval
      WHERE PropEval = 2
      

      【讨论】:

      • mysql 不支持 cte,很遗憾。
      • 非常抱歉,我没有意识到这只是 MySQL。我的错。
      【解决方案3】:

      这叫 Relational Division

      SELECT  a.name
      FROM    parent a
              INNER JOIN rel b
                  ON a.parent_ID = b.parent_ID
      WHERE   b.prop_id IN (1,5)
      GROUP BY a.name
      HAVING COUNT(*) = 2
      

      更新 1

      如果 唯一约束 没有对每个 parent_id 强制执行 prop_id,则在这种情况下需要 DISTINCT

      SELECT  a.name
      FROM    parent a
              INNER JOIN rel b
                  ON a.parent_ID = b.parent_ID
      WHERE   b.prop_id IN (1,5)
      GROUP BY a.name
      HAVING COUNT(DISTINCT b.prop_id) = 2
      

      【讨论】:

      • 这假设 parent_id 和 prop_id 的组合总是唯一的。您可以修改 HAVING 子句以更精确地返回:HAVING COUNT(DISTINCT b.prop_id) = 2
      • @Nicarus 是的,正如示例记录所示。但如果它们不是唯一的,假设表上有另一个字段使列唯一,则需要 DISTINCT 关键字。
      • 我很好奇 - 为什么需要 'count' 子句?
      • 查询返回的记录数等于条件值的个数,试试执行这个SELECT a.name FROM parent a INNER JOIN rel b ON a.parent_ID = b.parent_ID WHERE b.prop_id IN (1,5)看看有什么区别。
      • 我意识到我在这里错过了一块。将附加要求发布在:stackoverflow.com/questions/14113267/…
      【解决方案4】:

      我刚刚看到这个solution 提出了一个似乎适合这种情况的不同问题:

       SELECT distinct parent_id
       FROM rel as T1
       INNER JOIN rel as T2
       ON T1.parent_id = T2.parent_id
       WHERE T1.prop_id = '1' and T2.prop_id = '5'
      

      【讨论】:

      • 如果您需要找到另一个prop_id 怎么办?你需要再次加入吗?浪费资源。
      • 这可能会浪费计算资源,但答案是完全有效的,可能会为程序员节省大量的思考资源,因此值得考虑。不要过早优化!
      猜你喜欢
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-30
      相关资源
      最近更新 更多