关于SELECT COUNT DISTINCT两类查询结果差异的技术咨询
两类COUNT DISTINCT查询的结果差异解析
A组查询结果差异的核心原因
A组中两个查询的结果差异,来自NULL值的处理逻辑和去重维度的不同:
Query 1:子查询多列去重后统计行数
SELECT COUNT(*) FROM (SELECT DISTINCT COL1, COL2, COL3, COL4 FROM TABLE_A); -- RETURNS 11000
这个查询的逻辑是:
- 子查询对
COL1, COL2, COL3, COL4的列组合做去重,保留所有唯一的列组合行,包括含有NULL的组合(比如(1, 2, NULL, 3)和(1, 2, 3, NULL)会被视为两个不同的唯一行)。 - 外层的
COUNT(*)会统计子查询返回的所有行,包括带NULL的组合行,最终得到11000。
Query 2:子查询拼接后去重统计行数
SELECT COUNT(*) FROM (SELECT DISTINCT CONCAT(COL1, COL2, COL3, COL4) FROM TABLE_A); -- RETURNS 5699
这个查询的逻辑是:
CONCAT函数在多数SQL数据库中,只要任意一个参数是NULL,返回结果就是NULL。所有产生NULL的行在DISTINCT后只会保留一个NULL条目。- 同时,不同的列组合可能拼接出完全相同的字符串(比如
COL1='ab', COL2='c'和COL1='a', COL2='bc'拼接后都是'abc'),这类组合会被DISTINCT合并。 - 最终子查询返回的唯一字符串数量远少于Query1的列组合数量,所以外层
COUNT(*)得到5699。
B组查询结果一致的原因
B组改用COUNT(DISTINCT ...)语法后,两个查询的统计范围被统一,结果自然一致:
Query 1:COUNT(DISTINCT多列)
SELECT COUNT(DISTINCT COL1, COL2, COL3, COL4) FROM TABLE_A; -- RETURNS 5699
COUNT(DISTINCT 多列)的行为是仅统计所有列都非NULL的唯一组合——只要某列是NULL,该组合就会被COUNT函数忽略(因为COUNT不统计NULL值)。
Query 2:COUNT(DISTINCT拼接字符串)
SELECT COUNT(DISTINCT CONCAT(COL1, COL2, COL3, COL4)) FROM TABLE_A; -- RETURNS 5699
当任意列是NULL时,CONCAT结果为NULL,同样会被COUNT忽略;而所有列都非NULL时,拼接字符串与列组合是一一对应的(假设无不同组合拼接成相同字符串的情况),所以唯一字符串的数量和非NULL列组合的数量完全一致,最终都返回5699。
内容的提问来源于stack exchange,提问作者punsoca
相关产品推荐
相关产品推荐

