SQL查询以查找GROUPBY子句中所有行的总和和部分行的总和

SQL查询以查找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:

我正在尝试为SQLServer2008数据库构建查询。查询将对SID和日期列进行分组,并对利润列求和。查询还需要找到一天结束时具有相同单位的所有行的利润总和。在这种情况下,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

谢谢。

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