SQL查询,用于查找group by子句中所有行的总和以及行的各部分的总和

时间:2011-04-26 14:32:07

标签: sql sql-server sql-server-2008 group-by sum

我正在尝试为SQL Server 2008数据库构建查询。该查询将对SID和Date列进行分组,并对Profit列求和。查询还需要在一天结束时找到具有相同单位的所有行的利润总和。在这种情况下,单位值1从下午12:54从-1切换到1并保持不变直到当天的最后一个记录,即下午1:15。


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

感谢。

1 个答案:

答案 0 :(得分:1)

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
相关问题