在标准的SQL,我怎么在另一列中选择行使得对于一列的每个唯一值,所有的值都指定值?
问题描述:
在标准的SQL,我怎么在另一列中选择行使得对于一列的每个唯一值,所有的值都指定值?在标准的SQL,我怎么在另一列中选择行使得对于一列的每个唯一值,所有的值都指定值?
例如,在下表中,我想选择其中C_S的值“D”为C_1的每个不同的值列C_1的所有值。因此,对于c_1 ='2',c_s的所有值都是'd'。相同的c_1 ='3'。然而,这不是c_1 ='1','4'或'5'的情况。
这里是我的表:
id | c_1 | c_2 | c_s
----+------+---------+--------
1 | 1 | 1 | d
2 | 1 | 2 |
3 | 2 | 1 | d
4 | 2 | 2 | d
5 | 2 | 3 | d
6 | 3 | 1 | d
7 | 4 | 1 | r
8 | 5 | 1 | d
9 | 5 | 2 | r
这里是我想从我的SQL查询返回的内容:
c_1 | c_2 | c_s
----+---+--------
2 | 1 | d
3 | 1 | d
(我不知道如何词组这个问题 - 关键词等 - 请原谅,如果有更好的措辞,将导致解决方案已在此发布。)
答
您可以使用GROUP BY
和HAVING
:
SELECT c_1
, MIN(c_2) AS c_2
, MAX(c_s) AS c_s
FROM Table1
GROUP BY c_1
HAVING MIN(CASE WHEN c_s = 'd' THEN 1 ELSE 0 END)
+ MAX(CASE WHEN c_s = 'd' THEN 1 ELSE 0 END) = 2
演示:SQL Fiddle
在你即使c_2
存在其他值选择1
您的示例输出,所以我用MIN()
,但如果你想要一个不同的价值选择,即逻辑可以调整。
答
我的答案是非常相似的山羊CO的。我检查每个值的计数并将其与D的数量进行比较。
select
c_1 as 'c_1',
min(c_2) as 'c_2',
min(c_s) as 'c_s'
from yourTable
group by c_1
having count(1) = sum(case when c_s = 'd' then 1 else 0 end)
或者只是使having子句阅读:'HAVING MIN(C_S)= MAX(C_S)和C_S =“德' – jmarkmurphy 2014-09-05 19:34:46
谢谢!我明白了这一点。下面是我用什么'WITH newtable的AS(SELECT C_1,COUNT(DISTINCT(C_S))与CD,COUNT(C_S)作为CS,MIN(C_S)作为FS FROM test1的GROUP BY C_1 ORDER BY C_1)SELECT * FROM newtable的WHERE cds = 1 AND fs ='d''。你的解决方案也可行,所以我接受你的解决方案。 – 2014-09-05 19:36:52
@jmarkmurphy取决于缺失值是否为NULL或空白,NULL被聚合忽略并导致逻辑失败,但如果它是空白的,可以工作,尽管你需要最后一个'MAX(C_S)= '德',而不仅仅是'C_S =' 德',因为它是'HAVING'子句。 – 2014-09-05 19:51:38