17

给定一个父表'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 的所有父母?


编辑:同样的问题,但要求完全匹配: SQL 仅选择存在精确多重关系的行

4

4 回答 4

19

这称为关系除法

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

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

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
于 2012-12-31T06:26:43.393 回答
1

我刚刚看到这个似乎适合这种情况的不同问题的解决方案:

 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'
于 2012-12-31T06:32:25.783 回答
1

我已将您的表格写入 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
于 2012-12-31T06:39:13.717 回答
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)
于 2012-12-31T06:29:55.207 回答