SQL查询匹配具有连接的精确子项

时间:2018-02-09 11:19:00

标签: sql postgresql join

说我有以下表格

create table parent (parent_id)

create table child (child_id, parent_id, name)

以及以下行:

(1)
(2)
(3)

儿童

(11,1, "1")
(21,2, "1")
(22,2, "2")
(31,3, "1")
(32,3, "2")
(33,3, "3")

我需要找到仅包含名为(“1”,“2”)的子项的父项,即parent_id 2,但不包含parent_id 3。

通过简单快速的查询实现这一目标的方法是什么?

3 个答案:

答案 0 :(得分:1)

 SELECT * FROM parent WHERE   parent_id IN (SELECT parent_id FROM children WHERE name LIKE '1') AND parent_id IN (SELECT parent_id FROM children WHERE name LIKE '2')

答案 1 :(得分:1)

您可以将所有名称收集到一个数组中,并将其与您要查找的名称列表进行比较:

select parent_id
from child
group by parent_id
having array_agg(distinct name order by name) = array['1', '2']

order by name非常重要,因为['1', '2']不等于['2', '1']

答案 2 :(得分:1)

您想要 确切的关系部门 。以下内容应该为您提供所需的结果,但它假定parent_id, name对是唯一的:

SELECT parent_id
FROM child
GROUP BY parent_id
HAVING COUNT(CASE WHEN name     IN ('1', '2') THEN 1 END) = 2
AND    COUNT(*) = 2

备用且有点动态的解决方案如下:

WITH input(name) AS (
    SELECT '1' UNION
    SELECT '2'
)
SELECT child.parent_id
FROM child
LEFT JOIN input ON child.name = input.name
GROUP BY child.parent_id
HAVING COUNT(child.name) = (SELECT COUNT(*) FROM input)
AND    COUNT(input.name) = (SELECT COUNT(*) FROM input)