GROUP BY之后的总体DISTINCT COUNT

时间:2017-11-03 15:57:22

标签: sql sql-server group-by count

我有这些数据:

CREATE TABLE Person (
PersonID int PRIMARY KEY,
PersonName varchar(10),
Year int
);

INSERT INTO Person (PersonID, PersonName, Year)
VALUES (1, 'Ben', 2015),
(2, 'Sam', 2016),
(3,'Ben', 2016),
(4,'Fred', 2017),
(5,'Alex', 2016),
(6,'Ben', 2017);

现在,我正在尝试返回一个完全不同的计数。例如整个数据的唯一名称总数。

比如说,人们每年都会在系统上重新注册。 我如何回答一个问题,例如我需要从一开始就计算我们在系统上有多少人?请记住,Ben的2个条目是在几年内重新注册的同一个人,所以这只会算作1。

我最初的做法是这个

SELECT  min(Year), COUNT(DISTINCT PersonName) FROM
Person
GROUP BY Year

结果

2015    1
2016    3
2017    2

然而我知道这不对,因为它按年份分组,我正在寻找总共4而不是6.我只是错过了一些非常简单的东西吗?

sql fiddle - http://sqlfiddle.com/#!6/899cc8/2

4 个答案:

答案 0 :(得分:2)

Demo:

看来你是按年计算的;但不包括前几年已经发生过的名字数量。

因此我们使用row_number来识别每个personName的最早条目,然后按年计算每个personName的第1行。

WITH CTE as (
  SELECT [Year]
       , PersonName
       , ROW_NUMBER() OVER (PARTITION BY PersonName ORDER BY [Year] Asc) RN
  FROM Person)
SELECT Count(*), [Year]
FROM cte 
WHERE RN = 1
GROUP BY [Year]
ORDER BY [Year]

给我们:

+------+---------------+
| Year | UniqPersonCnt |
+------+---------------+
| 2015 |             1 |
| 2016 |             2 |
| 2017 |             1 |
+------+---------------+

你的例子不起作用的原因是因为名字的数量是按年份分组的,所以当你想要将它应用于整个集合时,仅适用于每年的不同。

这也是为什么我在评论中询问Ben何时需要被计算的原因。在最早的一年?最近一年?你期望每年看到什么?

答案 1 :(得分:1)

SELECT COUNT(DISTINCT personname) FROM person

答案 2 :(得分:1)

这是使用row_number()函数和派生表的另一种方法。有了这个,它以格式year |来显示数:

select year
      ,count(rn) as count_of_unique_name_by_year
from
(SELECT  Year
        ,row_number() over (partition by personname order by year) rn
FROM Person) t
where t.rn = 1
group by year

答案 3 :(得分:0)

正如Psidom所说,这就是你需要返回4的结果。

SELECT  COUNT(DISTINCT PersonName) 
FROM Person