TSQL - 遍历日期列表,组数据和插入表格

时间:2017-03-30 23:13:16

标签: sql-server tsql

所以我按以下格式将数据导入表中。对于缺少的任何月份,假设MM,App_Amt,ClaimCnt和UnqPtCnt列为0:

location|health_plan| plan_type | pcp |  MM  |App_Amt|ClaimCnt|UnqPtCnt|Date
SoJ     |BLUE SHIELD|    COM    | 2384|  18  | 0.00  |   0    |   0    |2014-01-01
SoJ     |BLUE SHIELD|    COM    | 2384|  20  |1430.08|   1    |   1    |2014-02-01
SoJ     |BLUE SHIELD|    COM    | 2384|  19  | 468.69|   4    |   3    |2014-03-01
SoJ     |BLUE SHIELD|    COM    | 2384|  19  | 184.12|   2    |   2    |2014-04-01
SoJ     |BLUE SHIELD|    COM    | 2384|  19  | 184.12|   2    |   2    |2014-05-01
SoJ     |BLUE SHIELD|    COM    | 2384|  15  |2321.79|   3    |   3    |2014-06-01
SoJ     |BLUE SHIELD|    COM    | 2384|  18  | 258.18|   2    |   2    |2014-07-01
SoJ     |BLUE SHIELD|    COM    | 2384|  22  | 258.18|   2    |   2    |2014-08-01
SoJ     |BLUE SHIELD|    COM    | 2384|  83  | 395.29|   3    |   2    |2014-09-01
SoJ     |BLUE SHIELD|    COM    | 2384|  28  | 258.18|   2    |   2    |2014-10-01
SoJ     |BLUE SHIELD|    COM    | 2384|  32  | 571.02|   4    |   4    |2014-11-01
SoJ     |BLUE SHIELD|    COM    | 2384|  14  | 258.18|   2    |   2    |2014-12-01    

我需要根据此数据集计算滚动/尾随12个月。我将取MM的平均值,App_Amt的总和,ClaimCnt的总和,以及UnqPtCt和按位置,health_plan,plan_type和PCP的总和的总和,我有一个我想要迭代的日期范围列表:

我从源表本身获取此日期列表。它目前是过去3年中的第一个月。下个月,数据将转变一个月。例如,现在它的最短日期为2014年1月1日,最长日期为11/01/2016,但下个月4月的最短日期为2014年1月1日,最长日期为12/01/2016

declare @end_dt date
set @end_dt = dateadd(month,-4,getdate())

select distinct [date] as start_dt,DATEADD(month,11,[date]) end_dt from [dbo].[OON_Summary]

select * from @Rolling where end_dt <= @end_dt


 start_dt | end_dt
2014-01-01|2014-12-01
2014-02-01|2015-01-01
2014-03-01|2015-02-01
2014-04-01|2015-03-01
2014-05-01|2015-04-01
2014-06-01|2015-05-01
2014-07-01|2015-06-01
2014-08-01|2015-07-01
2014-09-01|2015-08-01
2014-10-01|2015-09-01
2014-11-01|2015-10-01
2014-12-01|2015-11-01
2015-01-01|2015-12-01
2015-02-01|2016-01-01
2015-03-01|2016-02-01
2015-04-01|2016-03-01
2015-05-01|2016-04-01
2015-06-01|2016-05-01
2015-07-01|2016-06-01
2015-08-01|2016-07-01
2015-09-01|2016-08-01
2015-10-01|2016-09-01
2015-11-01|2016-10-01
2015-12-01|2016-11-01

到目前为止,我有这个简单的查询,但它太手动了,我知道必须有更好的方法来实现自动化。

declare @start_dt date 
declare @end_dt date 
set @start_dt = '2014-01-01'
set @end_dt = '2014-12-01'

insert into [dbo].[OON_Rolling12]
  SELECT 
  ,[location]
  ,[health plan]
  ,[plan_type]
  ,[pcp]
  ,AVG([MM]) [MM]
  ,SUM([App_Amt]) [App_Amt]
  ,SUM([ClaimCnt]) [ClaimCnt]
  ,SUM([UnqPtCnt]) UnqPtCnt
  ,@end_dt as AsOfDate
FROM [dbo].[OON_Summary]
WHERE [Date] >= @start_dt AND [Date] <= @end_dt
GROUP BY 
   [location]
  ,[health plan]
  ,[plan_type]
  ,[pcp]

运行查询一次将在下面的输出中生成第一行。基本上,我将2014年1月1日至2014年12月1日的所有数据分组,并将其称为2014年12月的数据。如何迭代该日期列表并自动生成其余行?

location|health_plan| plan_type | pcp |  MM  |App_Amt|ClaimCnt|UnqPtCnt |AsOfDate
SoJ     |BLUE SHIELD|    COM    | 2384|  25  |6565.83|   27   |   25    |2014-12-01
SoJ     |BLUE SHIELD|    COM    | 2384|  24  |6565.83|   27   |   25    |2015-01-01
SoJ     |BLUE SHIELD|    COM    | 2384|  22  |5135.75|   26   |   24    |2015-02-01
SoJ     |BLUE SHIELD|    COM    | 2384|  20  |4689.06|   22   |   21    |2015-03-01
SoJ     |BLUE SHIELD|    COM    | 2384|  19  |4504.94|   20   |   19    |2015-04-01
SoJ     |BLUE SHIELD|    COM    | 2384|  17  |4320.82|   18   |   17    |2015-05-01
SoJ     |BLUE SHIELD|    COM    | 2384|  16  |1999.03|   15   |   14    |2015-06-01
SoJ     |BLUE SHIELD|    COM    | 2384|  14  |1740.85|   13   |   12    |2015-07-01
SoJ     |BLUE SHIELD|    COM    | 2384|  13  |1482.67|   11   |   10    |2015-08-01
SoJ     |BLUE SHIELD|    COM    | 2384|  6   |1087.38|    8   |   8     |2015-09-01
SoJ     |BLUE SHIELD|    COM    | 2384|  3   |829.20 |    6   |   6     |2015-10-01
SoJ     |BLUE SHIELD|    COM    | 2384|  0   |258.18 |    2   |   2     |2015-11-01    
SoJ     |BLUE SHIELD|    COM    | 2384|  0   | 0.00  |    0   |   0     |2015-12-01    

1 个答案:

答案 0 :(得分:1)

您可以使用OUTER APPLY获取过去12个月的汇总值。

SELECT 
   o1.[location]
  ,o1.[health plan]
  ,o1.[plan_type]
  ,o1.[pcp]
  ,o2.[MM]
  ,o2.[App_Amt]
  ,o2.[ClaimCnt]
  ,o2.[UnqPtCnt]
FROM [dbo].[OON_Summary] o1
OUTER APPLY (SELECT AVG([MM]) as [MM]
                   ,SUM([App_Amt]) as [App_Amt]
                   ,SUM([ClaimCnt]) as [ClaimCnt]
                   ,SUM([UnqPtCnt]) as UnqPtCnt
             FROM [dbo].[OON_Summary] o2
             WHERE o1.[location]=o2.[location] AND o1.[health plan]=o2.[health plan] 
             AND o1.[plan_type]=o2.[plan_type] AND o1.[pcp]=o2.[pcp]
             AND o2.[date] BETWEEN DATEADD(month,-11,o1.[date]) AND o1.[date]
             ) o2

在具有窗口功能的sql server版本2012+中,这稍微容易一些。