如何对 SQL 个创建的列执行聚合
How to perform aggregation to SQL created columns
我在 SQL 服务器中有此数据
Name
Nationality
Gender
Anonymous
Chinese
M
Anonymous
Russian
F
Anonymous
German
F
Anonymous
Chinese
F
Anonymous
American
M
Anonymous
German
M
我可以 return 由不同值分隔的国籍计数:
SELECT
Nationality,
COUNT(*) AS [Nat.Count]
FROM
[table1]
GROUP BY
Nationality
Nationality
Nat.Count
Chinese
2
Russian
1
German
2
American
1
我该怎么做才能在底部附加一个“总计”行(见下文)? ...就像 Excel?
中的 AutoSum
Nationality
Nat.Count
Chinese
2
Russian
1
German
2
American
1
Total
6
这通常是一项前端工作...需要将其作为查询的一部分来执行有点奇怪。但是如果你必须...
SELECT Nationality, COUNT(*) AS [Nat.Count]
FROM [table1]
GROUP BY Nationality
UNION ALL
SELECT 'Total', COUNT(*)
FROM [table1]
作为使用 UNION
you can use GROUP BY ROLLUP
.
的替代方法
这种方法的优点是您不需要重复查询的主体 all-over-again。
因为 ROLLUP
使用 NULL
来忽略 grouping-keys,您需要使用 CTE 或 inner-query 使其适应 'Total', and/or 对其进行排序,使其成为最后一行,如下所示:
DECLARE @tbl AS TABLE (
Nationality nvarchar(100) NOT NULL,
Gender char(1) NOT NULL
);
INSERT INTO @tbl ( Nationality, Gender )
VALUES
( N'Chinese' , 'M' ),
( N'Russian' , 'F' ),
( N'German' , 'F' ),
( N'Chinese' , 'F' ),
( N'American', 'M' ),
( N'German' , 'M' );
-----
WITH counts AS (
SELECT
ROW_NUMBER() OVER ( ORDER BY Nationality ) AS r,
Nationality,
COUNT(*) AS "Nat.Count"
FROM
@tbl
GROUP BY ROLLUP
( Nationality )
)
SELECT
ISNULL( Nationality, 'Total' ) AS Nationality,
"Nat.Count"
FROM
counts
ORDER BY
/* This puts the 'Total' row last, but sorts all other rows by `Nationality`: */
CASE WHEN counts.Nationality IS NULL THEN 1 ELSE 0 END,
counts.r
或者,更简洁:
SELECT
ISNULL( t.Nationality, 'Total' ) AS Nationality,
COUNT(*) AS "Nat.Count"
FROM
@tbl AS t
GROUP BY ROLLUP
( t.Nationality )
ORDER BY
/* This puts the 'Total' row last, but sorts all other rows by `Nationality`: */
CASE WHEN t.Nationality IS NULL THEN 1 ELSE 0 END,
t.Nationality;
- 请注意,
GROUP BY ROLLUP
总是 要求 GROUP BY
列列表用括号分隔,即使您只指定一个列名。
- 所以这行不通:
GROUP BY ROLLUP
t.Nationality
Fun-fact:GROUP BY ROLLUP
也适用于具有内部标准的聚合函数,因此修改查询以添加按国家/地区细分的性别是微不足道的 and 得到总数:
SELECT
ISNULL( t.Nationality, 'Total' ) AS Nationality,
COUNT(*) AS "COUNT( People )",
COUNT( CASE Gender WHEN 'F' THEN 1 END ) AS "COUNT( Females )",
COUNT( CASE Gender WHEN 'M' THEN 1 END ) AS "COUNT( Males )",
COUNT( CASE WHEN Gender NOT IN ( 'F', 'M' ) THEN 1 END ) AS "COUNT( Other )"
FROM
@tbl AS t
GROUP BY ROLLUP
( t.Nationality )
ORDER BY
/* This puts the 'Total' row last, but sorts all other rows by `Nationality`: */
CASE WHEN t.Nationality IS NULL THEN 1 ELSE 0 END,
t.Nationality;
截图证明:
我在 SQL 服务器中有此数据
Name | Nationality | Gender |
---|---|---|
Anonymous | Chinese | M |
Anonymous | Russian | F |
Anonymous | German | F |
Anonymous | Chinese | F |
Anonymous | American | M |
Anonymous | German | M |
我可以 return 由不同值分隔的国籍计数:
SELECT
Nationality,
COUNT(*) AS [Nat.Count]
FROM
[table1]
GROUP BY
Nationality
Nationality | Nat.Count |
---|---|
Chinese | 2 |
Russian | 1 |
German | 2 |
American | 1 |
我该怎么做才能在底部附加一个“总计”行(见下文)? ...就像 Excel?
中的 AutoSumNationality | Nat.Count |
---|---|
Chinese | 2 |
Russian | 1 |
German | 2 |
American | 1 |
Total | 6 |
这通常是一项前端工作...需要将其作为查询的一部分来执行有点奇怪。但是如果你必须...
SELECT Nationality, COUNT(*) AS [Nat.Count]
FROM [table1]
GROUP BY Nationality
UNION ALL
SELECT 'Total', COUNT(*)
FROM [table1]
作为使用 UNION
you can use GROUP BY ROLLUP
.
这种方法的优点是您不需要重复查询的主体 all-over-again。
因为 ROLLUP
使用 NULL
来忽略 grouping-keys,您需要使用 CTE 或 inner-query 使其适应 'Total', and/or 对其进行排序,使其成为最后一行,如下所示:
DECLARE @tbl AS TABLE (
Nationality nvarchar(100) NOT NULL,
Gender char(1) NOT NULL
);
INSERT INTO @tbl ( Nationality, Gender )
VALUES
( N'Chinese' , 'M' ),
( N'Russian' , 'F' ),
( N'German' , 'F' ),
( N'Chinese' , 'F' ),
( N'American', 'M' ),
( N'German' , 'M' );
-----
WITH counts AS (
SELECT
ROW_NUMBER() OVER ( ORDER BY Nationality ) AS r,
Nationality,
COUNT(*) AS "Nat.Count"
FROM
@tbl
GROUP BY ROLLUP
( Nationality )
)
SELECT
ISNULL( Nationality, 'Total' ) AS Nationality,
"Nat.Count"
FROM
counts
ORDER BY
/* This puts the 'Total' row last, but sorts all other rows by `Nationality`: */
CASE WHEN counts.Nationality IS NULL THEN 1 ELSE 0 END,
counts.r
或者,更简洁:
SELECT
ISNULL( t.Nationality, 'Total' ) AS Nationality,
COUNT(*) AS "Nat.Count"
FROM
@tbl AS t
GROUP BY ROLLUP
( t.Nationality )
ORDER BY
/* This puts the 'Total' row last, but sorts all other rows by `Nationality`: */
CASE WHEN t.Nationality IS NULL THEN 1 ELSE 0 END,
t.Nationality;
- 请注意,
GROUP BY ROLLUP
总是 要求GROUP BY
列列表用括号分隔,即使您只指定一个列名。- 所以这行不通:
GROUP BY ROLLUP t.Nationality
- 所以这行不通:
Fun-fact:GROUP BY ROLLUP
也适用于具有内部标准的聚合函数,因此修改查询以添加按国家/地区细分的性别是微不足道的 and 得到总数:
SELECT
ISNULL( t.Nationality, 'Total' ) AS Nationality,
COUNT(*) AS "COUNT( People )",
COUNT( CASE Gender WHEN 'F' THEN 1 END ) AS "COUNT( Females )",
COUNT( CASE Gender WHEN 'M' THEN 1 END ) AS "COUNT( Males )",
COUNT( CASE WHEN Gender NOT IN ( 'F', 'M' ) THEN 1 END ) AS "COUNT( Other )"
FROM
@tbl AS t
GROUP BY ROLLUP
( t.Nationality )
ORDER BY
/* This puts the 'Total' row last, but sorts all other rows by `Nationality`: */
CASE WHEN t.Nationality IS NULL THEN 1 ELSE 0 END,
t.Nationality;
截图证明: