oracle 如何对多个列进行count(distinct)

6jjcrrmo  于 12个月前  发布在  Oracle
关注(0)|答案(6)|浏览(194)

这不起作用:

select count(distinct colA, colB) from mytable

我知道我可以简单地解决这个问题,使一个双重选择。

select count(*) from (
    select distinct colA, colB from mytable
)

有没有什么方法可以做到这一点,而不必做子选择?

nr7wwzry

nr7wwzry1#

子查询是我推荐的标准解决方案。基于级联的解决方案,除了在出现危险字符时容易出错之外,性能也可能更差。
注意:如果你收集了一些关于如何避免子查询的模糊解决方案,这里也可以使用窗口函数(不用于生产-你的代码评审员不会因此称赞你):

select distinct count(*) over ()
from my_table
group by colA, colB
jaxagkaj

jaxagkaj2#

[TL;DR]只需使用子查询。
如果你试图使用连接,那么你需要确保你用一个永远不会出现在值中的字符串来分隔术语,否则你会发现非独特的术语组合在一起。
举例来说:如果你有两个数字列,那么使用COUNT(DISTINCT col1 || col2)将把1||2312||3组合在一起,并把它们算作一个组。
你可以使用COUNT(DISTINCT col1 || '-' || col2),但如果列是字符串值,并且你有'ab-'||'-'||'c''ab'||'-'||'-c',那么,再次,它们一旦连接起来就相同。
最简单的方法是使用子查询。
如果你不能这样做,那么你可以通过字符串连接来合并组合列,但是你需要分析列的内容,并选择一个没有出现在你的字符串中的字符串,否则你的结果可能是错误的。更好的方法是确保带check约束的子字符串中永远不会出现这个字符串。

ALTER TABLE mytable ADD CONSTRAINT mytable__col1__chk CHECK (col1 NOT LIKE '%¬%');
ALTER TABLE mytable ADD CONSTRAINT mytable__col2__chk CHECK (col2 NOT LIKE '%¬%');

然后又道:

SELECT COUNT(DISTINCT col1 || '¬' || col2)
FROM   mytable;
o4tp2gmn

o4tp2gmn3#

只是为了好玩,你可以(ab)使用窗口函数和限制子句。这些是在分组后评估的。所以:

SELECT COUNT(*) OVER()
FROM t
GROUP BY col_a, col_b
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
rqqzpn5f

rqqzpn5f4#

如果你试图不惜一切代价避免子选择,一个变体是将它们连接起来:

SELECT count(DISTINCT concat(colA, colB)) FROM mytable;
tct7dpnv

tct7dpnv5#

把它们连接起来。

Select count(distinct colA ||'-'|| colB) from mytable;
omhiaaxx

omhiaaxx6#

  • NB:答案是SQLite*

还有一个使用JSON的方法:

SELECT count(DISTINCT json_object('colA', colA, 'colB', colB))
FROM mytable;

相关问题