Sql 仅选择所有行共有的条目
您好,我有这个表,只想查询所有行(日志Id)共有的条目。Sql 仅选择所有行共有的条目,sql,oracle,Sql,Oracle,您好,我有这个表,只想查询所有行(日志Id)共有的条目。 预期结果如下: PersonId Y/N Sex Rel 21 Y - ATH PerId Y/N S Rel 21 Y - ATH 22 N M ATH 您知道,我只想显示所有行的公共内容,否则为null。这只是一个非常复杂的查询的一部分。下面是一个大问题 Log Id Person Id Main
预期结果如下:
PersonId Y/N Sex Rel
21 Y - ATH
PerId Y/N S Rel
21 Y - ATH
22 N M ATH
您知道,我只想显示所有行的公共内容,否则为null。这只是一个非常复杂的查询的一部分。下面是一个大问题
Log Id Person Id Main(Y/N) Sex Rel
01 21 Y M ATH
02 21 Y M ATH
03 21 Y F ATH
04 21 Y M ATH
05 21 Y F ATH
01 22 N M ATH
02 22 N M ATH
03 22 N M ATH
04 22 N M ATH
05 22 N M ATH
预期结果如下:PersonId Y/N Sex Rel
21 Y - ATH
PerId Y/N S Rel
21 Y - ATH
22 N M ATH
以下查询应该可以工作:
select personId,
(case when count(distinct main)>1 then '' else main end) as Main,
(case when count(distinct sex) >1 then '' else sex end) as Sex,
(case when count(distinct religion)>1 then '' else religion end) as Religion
from yourTableName
group by personId;
结果:
personId | Main | Sex | Religion
21 | Y | | ATH
22 | N | M | ATH
ORACLE解决方案:(由@MarmiteBomber建议)
希望有帮助 我会这样写:
select personId,
(case when min(main) = max(main) then max(main) end) as Main,
(case when min(sex) = max(sex) then max(sex) end) as Sex,
(case when min(religion) = max(religion) then max(religion) end) as Religion
from yourTableName
group by personId;
注意:这使用NULL
表示未知值。我认为这更符合SQL。如果确实需要连字符,可以使用else'-'
为什么使用
min()
和max()
而不是count(distinct)
?原因很简单:性能count(distinct)
比其他聚合操作更昂贵(因为中间结果必须存储所有可能值的列表)。对于22
,您有Y
和N
。那么,对于22
,为什么结果应该包含N
?我得到了一个非personi列的非分组表达式。你确定你在使用MySQL吗?@TribensonAzupardo对于Oracle
你还必须使用聚合函数(如esMAX
或MIN
)来封装该列。例如,当count(distinct main)>1,然后NULL else max(main)end
@MarmiteBomber谢谢。您能解释一下这背后的原因吗?在使用groupby
的查询中,所有不在groupby中的引用属性都必须包含一个聚合函数。我想知道它如何在MySQL中工作。谢谢你提供的信息。但我有一个问题:假设有很多人信仰10-15种宗教。在这种情况下,min()和max()是否也比count()便宜?@Harshilmin()
和max()
比count(distinct)
快。问题是不同的。是的,这是正确的,尤其是当有更多的行时。