如何根据 SQL 中的分区对行求和?
Posted
技术标签:
【中文标题】如何根据 SQL 中的分区对行求和?【英文标题】:How to sum rows according to partition in SQL? 【发布时间】:2014-05-29 05:35:11 【问题描述】:如何根据分区在行内添加值,并且总和将放在每个分区下方(每个分区下方的新行将是总和的容器)?
使用以下链接: http://sqlfiddle.com/#!3/4e3e80/4
列名: 溢价、佣金、净溢价
col1 col2 col3
数据
124 213 producer
-1 12 producer
数据2
-1 312 producer
444 -555 producer
100 555 producer
col1 col2 col3
数据
124 213 producer
-1 12
123 225 null <<<<'result'
数据2
-1 312 producer
444 -555
100 555
543 312 null <<<<'result'
【问题讨论】:
你能发布一个预期结果的样本吗? 它在 excel 中。先生,我怎么发给你? 参考这个***.com/questions/23904192/… 并添加这样的输出。我的意思是你可以输入一个样本 @Nithesh:看看:D 希望cha
给你正确的答案。试试这样
【参考方案1】:
使用 ROLLUP:
这是一个包含几列的集合(仅限高级版)
SELECT
(CASE rno WHEN 1 THEN EndorsementId ELSE '' END )AS col1,
rno,
sum(PREMIUM)
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY EndorsementId ORDER BY PolicyNumber) AS rno,
*
FROM [endorsement]
) As temp1
GROUP by EndorsementId, rno
with rollup
结果:
| COL1 | RNO | COLUMN_2 |
|-------|--------|----------|
| 13519 | 1 | 750 |
| | 2 | 0 |
| | 3 | 0 |
| | (null) | 750 |
| 13524 | 1 | 157 |
| | 2 | 0 |
| | 3 | 158 |
| | 4 | 16 |
| | (null) | 331 |
. . . . . . .
SQL Fiddle
顺便说一句,Compute BY 可以达到相同的结果(它只是在 SQL Fiddle 中不起作用):
SELECT
(CASE rno WHEN 1 THEN EndorsementId ELSE '' END )AS col1,
rno,
PREMIUM
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY EndorsementId ORDER BY PolicyNumber) AS rno,
*
FROM [endorsement]
) As temp1
ORDER by EndorsementId, rno
COMPUTE SUM(Premium) BY EndorsementId
如果您无法忽略 ROLLUP 生成的最后一行,那么您可以使用以下语句生成包含组总计的所需结果。它有点长,但做得很好。 SQL Fiddle:
SELECT
(CASE rno WHEN 1 THEN EndorsementId WHEN 9999999999 THEN 'Total'ELSE '' END )AS [Endorsement ID],
(CASE rno WHEN 1 THEN PolicyNumber ELSE '' END )AS [Policy Number],
(CASE rno WHEN 1 THEN InsuredName ELSE '' END )AS [Insured Name],
(CASE rno WHEN 1 THEN [temp1].[EffectiveDate] ELSE '' END )AS [Effective Date],
(CASE rno WHEN 1 THEN [temp1].[ExpirationDate] ELSE '' END )AS [Expiration Date],
(CASE rno WHEN 1 THEN [temp1].[EndorsementNumber] ELSE '' END )AS [Endorsement Number],
(CASE rno WHEN 1 THEN [temp1].[EffectFromDate] ELSE '' END )AS [EffectFrom Date],
(CASE rno WHEN 1 THEN [temp1].[DueDate] ELSE '' END )AS [Due Date],
(CASE rno WHEN 1 THEN [temp1].[Producer] ELSE '' END )AS [Producer],
Premium,
Commission,
NetPremium AS [Net Premium]
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY EndorsementId ORDER BY PolicyNumber) AS rno,
*
FROM [endorsement]
UNION ALL
SELECT
9999999999 AS rno,
EndorsementId,
'',
'',
'',
'',
'',
'',
'',
'',
SUM(Premium) AS Premium,
SUM(Commission) AS Commission,
SUM(NetPremium) AS NetPremium
FROM [endorsement]
GROUP BY EndorsementId
) As temp1
ORDER BY EndorsementId, rno
【讨论】:
sqlfiddle.com/#!3/4e3e80/29 看看我的查询.. 你怎么能结合两个选择语句?谢谢 我认为rollup
组的最后一行将是您的结果
顺便说一句,最后一行是你的Grand Total
如何删除最后一行? :D 我不能在 SELECT 语句中添加这个列怎么样? (EndorsementId, PolicyNumber,InsuredName, EffectiveDate, ExpirationDate, EndorsementNumber,EffectFromDate,DueDate, Producer,
是的,你可以!我已经更新了答案并包含了一个不使用 ROLLUP 的解决方案【参考方案2】:
另一种方法是 UNION
将总行数添加到原始数据并以所需的方式对结果进行排序,直接与来自 fiddle 的数据链接是
SELECT
(CASE rno WHEN 1 THEN EndorsementId ELSE '' END )AS col1,
*
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY EndorsementId
ORDER BY PolicyNumber) AS rno,
*
FROM [endorsement]
UNION ALL
SELECT NULL As rno
, EndorsementId, PolicyNumber, InsuredName, EffectiveDate
, ExpirationDate, EndorsementNumber, EffectFromDate, DueDate, Producer
, Sum(Premium) Premium
, Sum(Commission) Commission
, Sum(NetPremium) NetPremium
From [endorsement]
Group By EndorsementId, PolicyNumber, InsuredName, EffectiveDate
, ExpirationDate, EndorsementNumber, EffectFromDate, DueDate, Producer
) As temp1
Order By EndorsementId, Coalesce(rno, 999)
【讨论】:
以上是关于如何根据 SQL 中的分区对行求和?的主要内容,如果未能解决你的问题,请参考以下文章