GROUP BY 如果组中至少一个值满足条件,则创建组
Posted
技术标签:
【中文标题】GROUP BY 如果组中至少一个值满足条件,则创建组【英文标题】:GROUP BY Create group if at least one value in group meets condition 【发布时间】:2017-11-27 05:24:26 【问题描述】:如果组中至少有一个值满足条件,如何创建组?
这是一个DB表test
的例子:
| ID | TYPE | COLOR |
|====|======|=======|
| 1 | 1 | R |
| 2 | 1 | B |
| 3 | 1 | G |
| 4 | 2 | B |
| 5 | 2 | G |
| 6 | 3 | G |
我需要选择所有具有多于一行的TYPE
值,并且该类型的颜色中至少有一个是 G。
所以伪选择看起来像这样:
select TYPE
from test
group by TYPE
having count(*) > 1
and count(COLOR = 'G') > 0
【问题讨论】:
COLOR 列中是否可以使用 NULL?同一种类型可以有重复的颜色吗?您使用什么版本的 Oracle? @mathguy ,在 COLOR 列中不能为 NULL,对于 TYPE 列中的相同值,COLOR 列中的重复值是可能的。还更正了问题“所有类型具有多于一种颜色且其中至少一种是 G”更改为“所有类型值具有多于一行,并且该类型的至少一种颜色是 G” 【参考方案1】:随着 OP 的修改要求:
select type
from test
group by type
having count(*) > 1 and count(case when color = 'G' then 0 end) > 0
;
【讨论】:
Hm... 它工作正常,但为什么该子句不是 case when color = 'G' then 1 else 0 end?在你的情况下它是如何工作的?如果color is G case语句返回0计为+1,如果color is not G case语句返回NULL,所以不计,对吧? 如果我使用 case when color = 'G' then 1 else 0 end 那么应该有另一个聚合函数 sum(case when color = 'G'然后 1 else 0 end) > 0,对吗? @IvanGerasimenko - 条件不是 case when ... - 它是 COUNT(case when ....)。不要遗漏 COUNT。 COUNT 计算所有非 NULL 值并且不关心那些非 NULL 值是什么;它不会把它们加起来,它只是计算它们。这与 SUM(case when....) 非常不同。在 COUNT(...) 方法中,我什至不需要使用数字;同样适用于count(case when color = 'G' then 'x' end)
。关键是当颜色不是G
时,case
表达式的else
部分没有分配非NULL 值。
@IvanGerasimenko - 有了 COUNT,我什至可以做到count(case when color = 'G' then SYSDATE end)
。 case
表达式现在具有 DATE 数据类型。没关系;颜色'G'的值将是非NULL,否则为NULL,这就是COUNT关心的全部。如果使用 SUM(CASE....),则无法在 CASE 表达式中分配字符或日期值,但使用 COUNT 可以。【参考方案2】:
您可以在计数(颜色)上使用内部连接
select t1.type
from test t1
inner join (
select type, count(color)
from test
where type in (select type from test where color='G' )
group by type
) t2 on t1.type = t2.type
group by t1.type
having count(*) > 1
或者用最简单的方式
select t1.type
from test t1
inner join test t2 on t1.type = t2.type and t2.color = 'G'
group by t1.type
having count(*) > 1
【讨论】:
不需要连接,一个聚合查询就足够了。【参考方案3】:count
只计算非null
值。将两个必需条件包装成一个的巧妙技巧是计算 case 表达式的不同数量,该表达式返回 G
的值和任何其他值的其他值:
SELECT type
FROM test
GROUP BY type
HAVING COUNT(DISTINCT CASE color WHEN 'G' THEN 1 ELSE 2 END) = 2
【讨论】:
这几乎是对的。您需要在 HAVING 子句中添加一个条件以检查count(case when color != 'G' then 1 end) > 0
以完全实现 OP 的要求。
@mathguy 哇,完全错过了,谢谢。请参阅我编辑的答案,了解将两个条件合并为一个的巧妙技巧。
:-) 我也是这么写的。或者(为了避免 DISTINCT) - max(case...) != min(case...)
以上是关于GROUP BY 如果组中至少一个值满足条件,则创建组的主要内容,如果未能解决你的问题,请参考以下文章