T-SQL聚合和递归

时间:2014-03-13 14:47:29

标签: sql sql-server tsql recursion common-table-expression

我确信必须有一个简洁的解决方案,但我似乎无法以我需要的方式工作。我相信你应该能够使用递归CTE来实现这一点。我试图避免创建大量的Tmp表。

主表(或递归锚点?)按人物,月份和数据聚合数据。年份并应用计数和&排名到结果

SELECT  
  PersonID
, Mth
, Yr
, COUNT(*) as DLY_Cnt
, RANK () OVER (PARTITION BY PersonID, Mth ORDER BY Yr DESC) as YrRnk
FROM #BkgSummary
GROUP BY PersonID, Mth, Yr

示例结果

PersonID    Mth     Yr  DLY_Cnt    Dep_YrRnk
6000995     6      2010    2           1
6000995     6      2009    1           2
6000995     6      2007    1           3
6000995     8      2011    2           1

我需要进一步聚合结果(并将其添加到之前的结果集),以基本上给出我在前几年同一个月内制作的预订数量(加上它自己的值)在PersonID&第M

类似于:SUM(DLY_Cnt) as DPY_Cnt by PersonID & Mth WHERE YrRnk >= Anchor YrRnk

我之后的示例结果:

PersonID    Mth     Yr  DLY_Cnt    Dep_YrRnk    DPY_Cnt
6000995     6      2010    2           1            4
6000995     6      2009    1           2            2
6000995     6      2007    1           3            1
6000995     8      2011    2           1            2

2 个答案:

答案 0 :(得分:2)

如果我正确理解结果,您需要累计总和DLY_Cnt。您可以在SQL Server 2012中轻松完成此操作:

SELECT PersonID, Mth, Yr, COUNT(*) as DLY_Cnt,
       RANK() OVER (PARTITION BY PersonID, Mth ORDER BY Yr DESC) as YrRnk,
       SUM(COUNT(*)) (PARTITION BY PersonId, Mth ORDER BY Yr) as DPY_Cnt
FROM #BkgSummary
GROUP BY PersonID, Mth, Yr;

您可以在早期版本中使用相关子查询执行类似的操作:

with t as (
      SELECT PersonID, Mth, Yr, COUNT(*) as DLY_Cnt,
             RANK() OVER (PARTITION BY PersonID, Mth ORDER BY Yr DESC) as YrRnk
      FROM #BkgSummary
      GROUP BY PersonID, Mth, Yr
     )
select t.*,
       (select sum(DLY_CNT)
        from t t2
        where t.PersonID = t2.PersonId and
              t.Yr = t2.Yr and
              t.Mth >= t2.Mth
       ) as DPY_Cnt
from t;

答案 1 :(得分:0)

试试这个......

  WITH CTE
AS (
    SELECT ID
        , MTH
        , YR
        , COUNT(*) AS DLY_CNT
        , DENSE_RANK() OVER (ORDER BY ID, MTH) DR
    FROM A
    GROUP BY ID
        , MTH
        , YR
    )
SELECT ID
    , MTH
    , DR
    , SUM(DLY_CNT)
FROM CTE
GROUP BY ID
    , MTH
    , DR