每个项目至少有一个分组

ara*_*lar 4 sql postgresql select relational-division

假设我有一个匹配person_ids 到pets的表。我有一份房主必须拥有的理想宠物清单(至少每只宠物之一),从下表中,我想看看谁符合要求。

该列表当然是(dog, cat, tiger). 人们绝对可以拥有不止一种,但这些都是必不可少的(因此person_id = 1是唯一有效的)。

+---------+-----------+--------+
| home_id | person_id |  pet   |
+---------+-----------+--------+
|       1 |         1 | dog    |
|       2 |         1 | dog    |
|       3 |         1 | cat    |
|       4 |         1 | tiger  |
|       5 |         2 | dog    |
|       6 |         2 | cat    |
|       7 |         3 | <null> |
|       8 |         4 | tiger  |
|       9 |         4 | tiger  |
|      10 |         4 | tiger  |
+---------+-----------+--------+
Run Code Online (Sandbox Code Playgroud)

我已经能够通过运行来检查谁有老虎或猫:

select person_id, pet 
from house 
group by person_id having pet in ('dog','cat','tiger'), 
Run Code Online (Sandbox Code Playgroud)

但显然,这给出了person_id至少拥有其中一只宠物的s - 不是所有宠物。

Mur*_*nik 5

一种方法是计算每个人有多少不同的宠物,并将其与不同宠物的总数进行比较(即加入):

SELECT person_id
FROM   (SELECT   person_id, COUNT(DISTINCT pet) AS dp
        FROM     pets
        GROUP BY person_id) a
JOIN   (SELECT COUNT(DISTINCT pet) AS dp FROM pets) b ON a.dp = b.dp
Run Code Online (Sandbox Code Playgroud)

编辑:
如果只有一些宠物被认为是“理想的”,并且该列表预先已知,则可以通过在where子句中引入此信息来大大简化查询:

SELECT   person_id
FROM     pets
WHERE    pet IN ('dog', 'cat', 'tiger')
GROUP BY person_id
HAVING   COUNT(DISTINCT pet) = 3
Run Code Online (Sandbox Code Playgroud)