分组不正确的结果不正确

时间:2018-06-21 21:15:16

标签: sql sql-server group-by

我有这两个查询,用于针对特定日期范围从表中计算出不同的计数。在我的第一个查询中,我按位置,aRID(这是一个规则)和日期进行分组。在第二个查询中,我没有按日期分组。

我期望两个结果中都具有相同的不同计数,但第一结果中的总计数为6147,第二结果中的总计数为6359。怎么了区别在于分组依据。

select
  r.loc 
 ,cast(r.date as DATE) as dateCol
 ,count(distinct r.dC) as dC_count
from table r
where r.date between '01-01-2018' and '06-02-2018'
and r.loc = 1
group by r.loc, r.aRId, cast(r.date as DATE)

select
r.loc 
,count(distinct r.DC) as dC_count
from table r
and r.date between '01-01-2018' and '06-02-2018'
and r.loc = 1
group by r.loc, r.aRId

loc dateCol     dC_count
1   2018-01-22  1
1   2018-03-09  2
1   2018-01-28  3
1   2018-01-05  1
1   2018-05-28  143
1   2018-02-17  1
1   2018-05-08  187
1   2018-05-31  146
1   2018-01-02  3
1   2018-02-14  1
1   2018-05-11  273
1   2018-01-14  1
1   2018-03-18  2
1   2018-02-03  1
1   2018-05-20  200
1   2018-05-14  230
1   2018-01-11  5
1   2018-01-31  1
1   2018-05-17  209
1   2018-01-20  2
1   2018-03-01  1
1   2018-01-03  3
1   2018-05-06  253
1   2018-05-26  187
1   2018-03-24  1
1   2018-02-09  1
1   2018-03-04  1
1   2018-05-03  269
1   2018-05-23  187
1   2018-05-29  133
1   2018-03-21  1
1   2018-03-27  1
1   2018-05-15  202
1   2018-03-07  1
1   2018-06-01  155
1   2018-02-21  1
1   2018-01-26  2
1   2018-02-15  2
1   2018-05-12  331
1   2018-03-10  1
1   2018-01-09  3
1   2018-02-18  1
1   2018-03-13  2
1   2018-05-09  184
1   2018-01-12  2
1   2018-03-16  1
1   2018-05-18  198
1   2018-02-07  1
1   2018-02-01  1
1   2018-01-15  3
1   2018-02-24  4
1   2018-03-19  1
1   2018-05-21  161
1   2018-02-10  1
1   2018-05-04  250
1   2018-05-30  148
1   2018-05-24  153
1   2018-01-24  1
1   2018-05-10  199
1   2018-03-08  1
1   2018-01-21  1
1   2018-05-27  151
1   2018-01-04  3
1   2018-05-07  236
1   2018-03-25  1
1   2018-03-11  2
1   2018-01-10  1
1   2018-01-30  1
1   2018-03-14  1
1   2018-02-19  1
1   2018-05-16  192
1   2018-01-13  5
1   2018-01-07  1
1   2018-03-17  3
1   2018-01-27  2
1   2018-02-22  1
1   2018-05-13  200
1   2018-02-08  2
1   2018-01-16  2
1   2018-03-03  1
1   2018-05-02  217
1   2018-05-22  163
1   2018-03-20  1
1   2018-02-05  2
1   2018-02-11  1
1   2018-01-19  2
1   2018-02-28  1
1   2018-05-05  332
1   2018-05-25  211
1   2018-03-23  1
1   2018-05-19  219

loc dC_count
1   6359

1 个答案:

答案 0 :(得分:1)

来自"COUNT (Transact-SQL)"

  

COUNT(DISTINCT表达式)计算组中每一行的表达式,并返回唯一的非空值的数量。

唯一性是相对于组的,而不是相对于整个表(或选定的子集)的。我认为这可能是您的误解。

为了更好地理解这意味着什么,请使用以下简化示例:

CREATE TABLE group_test
             (a varchar(1),
              b varchar(1),
              c varchar(1));

INSERT INTO group_test
            (a,
             b,
             c)
            VALUES ('a',
                    'r',
                    'x'),
                   ('a',
                    's',
                    'x'),
                   ('b',
                    'r',
                    'x'),
                   ('b',
                    's',
                    'y');

如果我们GROUP BY a并选择count(DISTINCT c)

SELECT a,
       count(DISTINCT c) #
       FROM group_test
       GROUP BY a;

我们得到

 a  | #
----|----
 a  |  1
 b  |  2

由于c='x'仅包含a=1,因此该组仅包含1个'x''y',而其他组只有2个在c中。这里的总数为3。

现在,如果我们GROUP BY a, b

SELECT a,
       b,
       count(DISTINCT c) #
       FROM group_test
       GROUP BY a,
                b;

我们得到

 a  | b  | #
----|----|----
 a  | r  |  1
 a  | s  |  1
 b  | r  |  1
 b  | s  |  1

这里,每个计数得到1,因为c的每个值都是组中唯一的一个。突然计数总计为4。

如果我们得到整个表的c个不同的计数

SELECT count(DISTINCT c) #
       FROM group_test;

我们得到

 #  
----
  2  

总计2。

每种情况下的计数总和都不同,但仍然正确。

组越多,该值在该组中唯一的机会就越大。因此,您的结果似乎完全合理。

db<>fiddle