Подтвердить что ты не робот

SQL Выберите только строки, в которых существует несколько взаимосвязей

Учитывая родительскую таблицу "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 Выберите только строки, в которых существуют точные множественные отношения

4b9b3361

Ответ 1

Это называется 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

если единственное ограничение не выполнялось в prop_id для каждого parent_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

Ответ 2

назовите свою первую таблицу 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)

Ответ 3

Я только что увидел это решение по другому вопросу, который, по-видимому, соответствует этому случаю:

 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'

Ответ 4

Я написал вашу таблицу в 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