通过每个项目至少有一个来分组

Posted

技术标签:

【中文标题】通过每个项目至少有一个来分组【英文标题】:Group by having at least one of each item 【发布时间】:2015-08-20 15:49:25 【问题描述】:

假设我有一个匹配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  |
+---------+-----------+--------+

我已经能够通过跑步检查谁有老虎或猫:

select person_id, pet 
from house 
group by person_id having pet in ('dog','cat','tiger'), 

但显然这给了person_ids 至少拥有这些宠物中的一只——而不是全部。

【问题讨论】:

你的主键是什么? 【参考方案1】:

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

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

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

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

【讨论】:

所以问题在于一些宠物,例如rabbits 不起作用,这会“污染”结果。不过谢谢! @miguel5 出于某种原因,我误解了这个问题,好像桌子上不可能有不理想的宠物。通过改进的查询查看我编辑的答案。 谢谢!! (公平地说,我没有说这是一个要求)【参考方案2】:
select person_id
from house 
where pet = 'dog'
intersect
select person_id
from house 
where pet = 'cat'
intersect
select person_id
from house 
where pet = 'tiger'

您可以使用intersect 获取拥有全部 3 只宠物的人。

【讨论】:

这个问题是实际查询需要几个连接,但是谢谢!【参考方案3】:

您可以通过单独计算每只宠物来做到这一点,如下所示:

select
    person_id 
FROM MyTable
GROUP BY person_id
HAVING 3 = (
    MAX(CASE pet WHEN 'dog' THEN 1 ELSE 0 END)
+   MAX(CASE pet WHEN 'cat' THEN 1 ELSE 0 END)
+   MAX(CASE pet WHEN 'tiger ' THEN 1 ELSE 0 END)
)

组中的每个MAX 在此人拥有相应宠物时为1,在此人没有该宠物时为0。每个至少有一个的组将在HAVING 子句的过滤器中产生3 的总和。

【讨论】:

以上是关于通过每个项目至少有一个来分组的主要内容,如果未能解决你的问题,请参考以下文章

力扣570(MySQL)-至少有5名直接下属的经理(简单)

对象导论系列---每个对象都至少有一个接口

FlatList 仅在至少有 2 个项目时才可见

在 JPA 中怎么说,给我 Collection 字段在另一个列表中至少有一个项目的所有对象?

错误:C2016 C 要求结构或联合至少有一个成员

查找文本文件中至少有两个共同单词的所有行(Bash)