如何计算具有多个日期的运行总列的标准

时间:2016-08-23 17:50:22

标签: sql-server tsql sql-server-2012

我正在使用SQL Server 2012,并且我需要将查询转换为每月的运行总计。

当前查询需要输入日期输入参数,并输出所有组,每组输入月份日期

DECLARE @InputDate DATETIME
SET MonthEndDate = '2016/07/31'

SELECT P.GroupID,Count(P.PersonID) as GroupTotal
from PersonData P
WHERE 
     P.StartedDate IS NOT NULL
AND P.StartedDate < @InputDate
AND (
     P.OutcomeDate > @InputDate
     OR P.OutcomeDate IS NULL 
)
GROUP BY  P.GroupID

使用相同的查询逻辑我现在需要每月重新填充历史数据,因此我需要使用所有月份的运行总计,例如(2016/01 / 01,2016 / 02 / 01,2016 / 03/01等)而非特定月份

如果有一个日期条件,我可以这样做,例如对于StartedDate e.g。

SELECT P.*,
SUM(GroupTotal)  OVER (PARTITION BY GroupID ORDER BY StartedMonth) AS RunningTotal


FROM (
        SELECT P.GroupID,LEFT(CONVERT(VARCHAR, P.StartedDate, 112), 6) as StartedMonth,Count(P.PersonID) as GroupTotal
        from PersonData P
        WHERE 
             P.StartedDate IS NOT NULL

        GROUP BY  P.GroupID,LEFT(CONVERT(VARCHAR, P.StartedDate, 112), 6)
    ) P
    ORDER BY GroupID,StartedMonth

但我的原始查询有两个日期条件而不仅仅是一个

1. P.StartedDate < @InputDate
2. P.OutcomeDate > @InputDate or P.OutcomeDate IS NULL 

是否可以编写一个查询,其中包含多个运行总计的日期条件

编辑:

以下是输入PersonData表的示例

PersonID,GroupID,StartedDate,OutcomeDate
1,1001,'2016/05/08',null
2,1001,'2016/05/04','2016/08/03'
3,1001,'2016/06/04','2016/08/03'
4,1001,'2016/07/04','2016/07/07'
5,1001,'2016/07/04','2016/08/08'
6,1001,'2016/08/04','2016/09/03'
7,1001,'2016/08/04','2016/09/03'
8,1001,'2016/09/04','2016/09/08'

预期产出

GroupId,EndMonthDate,MonthCount, RTMonthCount
1001,'2016/05/31', 2, 2
1001,'2016/06/30', 1, 3
1001,'2016/07/31', 1, 4
1001,'2016/08/31', 2, 6
1001,'2016/09/31', 0, 6

所以在上面的例子中你可以看到人物ID 4&amp; 8不算作唯一的标准,没有匹配,而不是标准2。

1 个答案:

答案 0 :(得分:0)

如下所示,您需要PARTITION BY(GroupID,StartedMonth)来计算每个月的总数,并且对于运行总计,请执行“无限制预设和当前行之间的行”

SELECT P.*,
SUM(GroupTotal) OVER (PARTITION BY GroupID, StartedMonth) AS MonthTotal,
SUM(GroupTotal)  OVER (PARTITION BY GroupID ORDER BY StartedMonth ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningTotal
FROM (
        SELECT P.GroupID,LEFT(CONVERT(VARCHAR, P.StartedDate, 112), 6) as StartedMonth,Count(P.PersonID) as GroupTotal
        from PersonData P
        WHERE 
             P.StartedDate IS NOT NULL

        GROUP BY  P.GroupID,LEFT(CONVERT(VARCHAR, P.StartedDate, 112), 6)
    ) P
    ORDER BY GroupID,StartedMonth

请查看此链接:Calculate a Running Total in SQL Server

**第二个版本,为子查询添加了一个条件

SELECT P.*,
SUM(GroupTotal) OVER (PARTITION BY GroupID, StartedMonth) AS MonthTotal,
SUM(GroupTotal)  OVER (PARTITION BY GroupID ORDER BY StartedMonth ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningTotal
FROM (
        SELECT P.GroupID,LEFT(CONVERT(VARCHAR, P.StartedDate, 112), 6) as StartedMonth,Count(P.PersonID) as GroupTotal
        from PersonData P
        WHERE 
             P.StartedDate IS NOT NULL
             AND (P.OutcomeDate IS NULL OR (P.OutcomeDate> EOMONTH(P.StartedDate)))    
        GROUP BY  P.GroupID,LEFT(CONVERT(VARCHAR, P.StartedDate, 112), 6)
    ) P
    ORDER BY GroupID,StartedMonth