SQL查询以查找GROUPBY子句中所有行的总和和部分行的总和
我正在尝试为SQLServer2008数据库构建查询。查询将对SID和日期列进行分组,并对利润列求和。查询还需要找到一天结束时具有相同单位的所有行的利润总和。在这种情况下,1的单位值从下午12:54的-1切换到1,并保持不变,直到那天的最后一个记录是下午1:15SQL查询以查找GROUPBY子句中所有行的总和和部分行的总和,sql,sql-server,sql-server-2008,group-by,sum,Sql,Sql Server,Sql Server 2008,Group By,Sum,我正在尝试为SQLServer2008数据库构建查询。查询将对SID和日期列进行分组,并对利润列求和。查询还需要找到一天结束时具有相同单位的所有行的利润总和。在这种情况下,1的单位值从下午12:54的-1切换到1,并保持不变,直到那天的最后一个记录是下午1:15 SID Date Profit Units RowID ------------------------------------------------------- 1 7/26/10 1:
SID Date Profit Units RowID
-------------------------------------------------------
1 7/26/10 1:15 PM -25 1 1
1 7/26/10 12:54 PM -12.5 1 2
1 7/26/10 12:54 PM 0 0 3
1 7/26/10 12:54 PM -125 -1 4
1 7/26/10 12:00 PM 100 -1 5
1 7/26/10 10:31 AM -50 -1 6
包含0个单位的行表示发生了切换。第三行的单位并不总是更改为0。比如说,
SID Date Profit Units
--------------------------------------------------------
1 7/26/10 2:15 PM -37.5 -1
1 7/26/10 2:06 PM -125 -1
1 7/26/10 2:00 PM -12.5 -1
1 7/26/10 2:00 PM 0 0
1 7/26/10 2:00 PM -75 1
1 7/26/10 12:45 PM -12.5 1
1 7/26/10 12:45 PM 0 0
1 7/26/10 12:45 PM -125 -1
1 7/26/10 12:00 PM 100 -1
1 7/26/10 9:55 AM -50 -1
第一个数据集的输出如下所示:
SID Date TotalProfit ProfitforEndofDayUnits
-------------------------------------------------------
1 7/26/10 -112.5 -37.5
谢谢。Mikael,您构建的查询适用于问题中的第一个数据集。当我尝试第二个数据集时,它没有给出正确的结果。您能检查一下吗?“C2.rn=1”查找与模式匹配的所有行(在本例中,单位为-1),它不是只查找顶部的三行,而是返回数据集中的6行。@ARK–我已经更新了查询,使其只返回到
Unit
中的更改。Mikael,您构建的查询适用于问题中的第一个数据集。当我尝试第二个数据集时,它没有给出正确的结果。您能检查一下吗?“C2.rn=1”查找与模式匹配的所有行(在本例中,单位为-1),它不是只查找顶部的三行,而是返回数据集中的6行。@ARK–我已更新查询,只对单位的更改进行计数。
declare @T table(
[SID] int,
[Date] datetime,
Profit money,
Units int)
insert into @T values
(1, '7/26/10 2:15 PM', -37.5, -1),
(1, '7/26/10 2:06 PM', -125, -1),
(1, '7/26/10 2:00 PM', -12.5, -1),
(1, '7/26/10 2:00 PM', 0, 0),
(1, '7/26/10 2:00 PM', -75, 1),
(1, '7/26/10 12:45 PM', -12.5, 1),
(1, '7/26/10 12:45 PM', 0, 0),
(1, '7/26/10 12:45 PM', -125, -1),
(1, '7/26/10 12:00 PM', 100, -1),
(1, '7/26/10 9:55 AM', -50, -1),
(2, '7/26/10 1:15 PM', -25, 1),
(2, '7/26/10 12:54 PM', -12.5, 1),
(2, '7/26/10 12:54 PM', 0, 0),
(2, '7/26/10 12:54 PM', -125, -1),
(2, '7/26/10 12:00 PM', 100, -1),
(2, '7/26/10 10:31 AM', -50, -1)
;with cte as
(
select
[SID],
cast([Date] as Date) as [Date],
Profit,
Units,
row_number() over(partition by SID, cast([Date] as Date)
order by [Date] desc) as rn
from @T
)
select
C1.[SID],
C1.[Date],
sum(C1.Profit) as TotalProfit,
sum(case when C2.Units = C1.Units and
C1.rn < S.rn
then C1.Profit
else 0.0
end) ProfitforEndofDayUnits
from cte as C1
inner join cte as C2
on C1.[SID] = C2.[SID] and
C1.[Date] = C2.[Date] and
C2.rn = 1
cross apply
(select min(C3.rn) as rn
from cte as C3
where C1.[SID] = C3.[SID] and
C1.[Date] = C3.[Date] and
C3.Units <> C2.Units) as S
group by C1.[SID], C1.[Date]
SID Date TotalProfit ProfitforEndofDayUnits
----------- ---------- --------------------- -----------------------
1 2010-07-26 -337,50 -175.0000
2 2010-07-26 -112,50 -37.5000