计算具有多个聚合列的行

Posted

技术标签:

【中文标题】计算具有多个聚合列的行【英文标题】:Count rows with multiple aggreagate columns 【发布时间】:2012-12-11 00:00:37 【问题描述】:

我有一个测试表来演示这个问题:

Id  NetworkId   CountryCode
1       1           de
2       2           de
3       2           de
4       2           de
5       1           us
6       1           us
7       1           us
8       2           us

我需要输出如下内容:

NetworkId   CountryCode    DistCount
    1           de              1
    2           de              3
    1           us              3
    2           us              1

尝试的查询

我在 SO 上寻找了几个答案,但我无法找到我需要的确切答案。这是第一个相关问题和我尝试过的查询:Counting the rows of multiple distinct columns

查询:

SELECT NetworkId, CountryCode, COUNT(*) as DistCount
FROM (SELECT DISTINCT NetworkId, CountryCode FROM TestTable) AS FOO
GROUP BY NetworkId, CountryCode

结果:

NetworkId   CountryCode    DistCount
    1           de              1
    1           us              1
    2           de              1
    2           us              1

查询:

SELECT COUNT(DISTINCT(STR(NetworkId) + ',' + STR(CountryCode)))
FROM TestTable

结果:

Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to float.

我也试过这个问题的答案:How can I count distinct multiple fields without repeating the query?

查询:

SELECT 
   NetworkId, 
   CountryCode,
   COUNT(*) OVER(PARTITION BY NetworkId, CountryCode) as DistCount
FROM TestTable
GROUP BY NetworkId, CountryCode

结果:

NetworkId   CountryCode    DistCount
    1           de              1
    1           us              1
    2           de              1
    2           us              1

如您所知,我很难弄清楚如何做到这一点......我认为它应该相对简单,但我错过了一些东西。

【问题讨论】:

【参考方案1】:

如果 Id 在 TestTable 中是唯一的且不为空(如果它是主键则为空),则此查询将返回您指定的结果集:

SELECT NetworkId, CountryCode, Count(1) AS DistCount
  FROM TestTable 
 GROUP BY NetworkId, CountryCode
 ORDER BY NetworkId, CountryCode

但是,如果 Id 列不是唯一的,并且您想要的是每个组中不同的非空 Id 值的计数,则可以添加 DISTINCT 关键字:

SELECT NetworkId, CountryCode, Count(DISTINCT Id) AS DistCount
  FROM TestTable 
 GROUP BY NetworkId, CountryCode
 ORDER BY NetworkId, CountryCode

根据您的示例数据,两个查询都将返回相同的结果。仅当您在组中具有重复的 Id 值时才会有所不同。

【讨论】:

@Lirik:当我想要返回的是行数时,我通常使用COUNT(1)。请注意,这会返回等效于SUM(1) 的结果,这在概念上是有意义的,因为对于包含在组中的每一行,我们实际上是在将行计数器递增 1。当我们使用其他表达式时,例如COUNT(Id),它只会增加非 NULL 值的计数器。相当于SUM(IF Id IS NULL THEN 0 ELSE 1)。当我们添加 DISTINCT 关键字时,例如COUNT(DISTINCT Id),现在我们只在未包含非 NULL 值时增加行计数器【参考方案2】:

除非我弄错了,否则这是可行的:

SELECT NetworkId, CountryCode, COUNT(Id) as DistCount
FROM TestTable
GROUP BY NetworkId, CountryCode

【讨论】:

好的,这行得通...让我看看它是否适用于我的实际查询,因为那里的事情有点复杂。 这也是SQLFiddle 的支持。 (啊,刚刚被打败了) @Lirik - 如果您的查询相当复杂,您可能需要向我们展示其余部分,以便我们为您提供更好的帮助。 @Clockwork-Muse 这是一个更大的查询,但它涉及太多其他不相关的内容。这是我缺少的关键部分,现在它就像一个魅力!

以上是关于计算具有多个聚合列的行的主要内容,如果未能解决你的问题,请参考以下文章

带有子查询的 SQL 多个聚合函数

在聚合查询中计算具有特定条件的行

pandas编写自定义函数计算多个数据列的加和(sum)使用groupby函数和apply函数聚合计算分组内多个数据列的加和

在保留列的同时计算具有相同值的行

如果我的 PLSQL 块中有多个 DML 查询,我如何计算聚合受影响的行?

MySQL的聚合函数