SQL - 创建存储过程以循环遍历日期以计算度量
SQL - Creating stored procedure to loop through dates to calculate a measure
问题 - 我正在尝试创建一个存储过程,该过程将 运行 每季度计算一个指标(在这种情况下,一个总和)超过移动的一年 window 的每月历史数据数据,其中计算从季度第一天之前的三个月开始,并回顾该日期之前的一年。因此,当程序 运行s 在 4/1/2015 时,我想计算从 1/1/2014 到 12/31/2014 的指标。 2015 年 7 月 1 日,我想计算从 2014 年 4 月 1 日到 2015 年 3 月 31 日的指标。一直持续下去。 (它还必须包括基于历史季度的指标计算。)
因为这是一个定期 运行 的分析,我需要自动执行该过程,我认为某种循环是合适的。我是 SQL 中的编程新手 - 我的经验几乎完全是查询 - 如果有任何帮助,我们将不胜感激。
就目前而言,我的数据如下所示(对长度表示歉意):
ID Month Metric
123456 1/1/2011 7
123456 2/1/2011 4
123456 3/1/2011 8
123456 4/1/2011 2
123456 5/1/2011 0
123456 6/1/2011 7
123456 7/1/2011 4
123456 8/1/2011 0
123456 9/1/2011 7
123456 10/1/2011 4
123456 11/1/2011 6
123456 12/1/2011 0
123456 1/1/2012 0
123456 2/1/2012 2
123456 3/1/2012 7
123456 4/1/2012 3
123456 5/1/2012 5
123456 6/1/2012 6
123456 7/1/2012 5
123456 8/1/2012 5
123456 9/1/2012 1
123456 10/1/2012 5
123456 11/1/2012 2
123456 12/1/2012 7
123456 1/1/2013 5
123456 2/1/2013 7
123456 3/1/2013 5
987654 1/1/2011 2
987654 2/1/2011 0
987654 3/1/2011 7
987654 4/1/2011 5
987654 5/1/2011 6
987654 6/1/2011 8
987654 7/1/2011 4
987654 8/1/2011 4
987654 9/1/2011 3
987654 10/1/2011 3
987654 11/1/2011 3
987654 12/1/2011 2
987654 1/1/2012 5
987654 2/1/2012 2
987654 3/1/2012 3
987654 4/1/2012 8
987654 5/1/2012 5
987654 6/1/2012 7
987654 7/1/2012 6
987654 8/1/2012 0
987654 9/1/2012 3
987654 10/1/2012 6
987654 11/1/2012 6
987654 12/1/2012 6
987654 1/1/2013 0
987654 2/1/2013 4
987654 3/1/2013 4
编写查询以获取任何一个季度(2012 年第一季度)的结果非常容易:
SELECT DISTINCT ID, '01' AS Quarter, '2012' AS Year, SUM(Metric) AS Metric
FROM TABLE_1
WHERE (Month >= '1/1/2011' AND Month < '1/1/2012')
GROUP BY ID
输出:
ID Quarter Year Metric
123456 01 2012 49
为每个季度的分析编写一个变体显然是低效的(而且对于我正在尝试创建的内容无论如何都不起作用),因此目标是编写某种循环来自动化该过程。
所需的输出如下所示:
ID Quarter Year Metric
123456 01 2012 49
123456 02 2012 39
123456 03 2012 44
123456 04 2012 44
123456 01 2013 51
987654 01 2012 47
987654 02 2012 48
987654 03 2012 49
987654 04 2012 47
987654 01 2013 57
我被卡住了,我在 SQL 中缺乏编程经验被证明是一个挑战。关于如何进行的任何建议?提前致谢!
SELECT DISTINCT ID,
Qtr = DATEPART(qq,DATEADD(month, -15, [Month])),
Yr = DATEPART(yy,DATEADD(month, -15, [Month])),
Sum(Metric) AS Metric
FROM TABLE_1
GROUP BY ID, DATEPART(qq,DATEADD(month, -15, [Month])), DATEPART(yy,DATEADD(month, -15, [Month]))
假设您的 table 季度数据如下所示:
CREATE TABLE QtrData(
ID INT NULL,
Qtr INT NULL,
Yr INT NULL,
Metric INT NULL
)
这个程序可以满足您的需求:
CREATE PROC dbo.spInsertQuarterlyData
@Dt datetime
AS
DECLARE @CurrQtrDt DATETIME
DECLARE @RangeStartDt DATETIME
DECLARE @RangeEndDt DATETIME
SELECT @CurrQtrDt = DATEADD(qq, DATEDIFF(qq, 0, @Dt), 0)
SELECT @RangeStartDt = DATEADD(mm,-15,@CurrQtrDt)
SELECT @RangeEndDt = DATEADD(dd,-1,DATEADD(mm,-3,@CurrQtrDt))
INSERT INTO QtrData( ID, Qtr, Yr, Metric )
SELECT
ID,
DATEPART(qq,@CurrQtrDt)-1,
DATEPART(yyyy,@CurrQtrDt),
SUM(Metric)
FROM Table_1
WHERE [Month] BETWEEN @RangeStartDt AND @RangeEndDt
GROUP BY ID
然后您将安排一个 SQL 作业每季度执行一次此过程,将 GETDATE()
作为参数传入。
要使用初始问题陈述中的历史数据填充 table,最简单的方法是调用此过程循环遍历历史季度,如下所示:
DECLARE @Dt datetime
SET @dt = '1/1/2011'
WHILE @dt < GETDATE()
BEGIN
EXEC dbo.spInsertQuarterlyData @dt
SET @dt = DATEADD(mm,3,@Dt)
END
问题 - 我正在尝试创建一个存储过程,该过程将 运行 每季度计算一个指标(在这种情况下,一个总和)超过移动的一年 window 的每月历史数据数据,其中计算从季度第一天之前的三个月开始,并回顾该日期之前的一年。因此,当程序 运行s 在 4/1/2015 时,我想计算从 1/1/2014 到 12/31/2014 的指标。 2015 年 7 月 1 日,我想计算从 2014 年 4 月 1 日到 2015 年 3 月 31 日的指标。一直持续下去。 (它还必须包括基于历史季度的指标计算。)
因为这是一个定期 运行 的分析,我需要自动执行该过程,我认为某种循环是合适的。我是 SQL 中的编程新手 - 我的经验几乎完全是查询 - 如果有任何帮助,我们将不胜感激。
就目前而言,我的数据如下所示(对长度表示歉意):
ID Month Metric
123456 1/1/2011 7
123456 2/1/2011 4
123456 3/1/2011 8
123456 4/1/2011 2
123456 5/1/2011 0
123456 6/1/2011 7
123456 7/1/2011 4
123456 8/1/2011 0
123456 9/1/2011 7
123456 10/1/2011 4
123456 11/1/2011 6
123456 12/1/2011 0
123456 1/1/2012 0
123456 2/1/2012 2
123456 3/1/2012 7
123456 4/1/2012 3
123456 5/1/2012 5
123456 6/1/2012 6
123456 7/1/2012 5
123456 8/1/2012 5
123456 9/1/2012 1
123456 10/1/2012 5
123456 11/1/2012 2
123456 12/1/2012 7
123456 1/1/2013 5
123456 2/1/2013 7
123456 3/1/2013 5
987654 1/1/2011 2
987654 2/1/2011 0
987654 3/1/2011 7
987654 4/1/2011 5
987654 5/1/2011 6
987654 6/1/2011 8
987654 7/1/2011 4
987654 8/1/2011 4
987654 9/1/2011 3
987654 10/1/2011 3
987654 11/1/2011 3
987654 12/1/2011 2
987654 1/1/2012 5
987654 2/1/2012 2
987654 3/1/2012 3
987654 4/1/2012 8
987654 5/1/2012 5
987654 6/1/2012 7
987654 7/1/2012 6
987654 8/1/2012 0
987654 9/1/2012 3
987654 10/1/2012 6
987654 11/1/2012 6
987654 12/1/2012 6
987654 1/1/2013 0
987654 2/1/2013 4
987654 3/1/2013 4
编写查询以获取任何一个季度(2012 年第一季度)的结果非常容易:
SELECT DISTINCT ID, '01' AS Quarter, '2012' AS Year, SUM(Metric) AS Metric
FROM TABLE_1
WHERE (Month >= '1/1/2011' AND Month < '1/1/2012')
GROUP BY ID
输出:
ID Quarter Year Metric
123456 01 2012 49
为每个季度的分析编写一个变体显然是低效的(而且对于我正在尝试创建的内容无论如何都不起作用),因此目标是编写某种循环来自动化该过程。
所需的输出如下所示:
ID Quarter Year Metric
123456 01 2012 49
123456 02 2012 39
123456 03 2012 44
123456 04 2012 44
123456 01 2013 51
987654 01 2012 47
987654 02 2012 48
987654 03 2012 49
987654 04 2012 47
987654 01 2013 57
我被卡住了,我在 SQL 中缺乏编程经验被证明是一个挑战。关于如何进行的任何建议?提前致谢!
SELECT DISTINCT ID,
Qtr = DATEPART(qq,DATEADD(month, -15, [Month])),
Yr = DATEPART(yy,DATEADD(month, -15, [Month])),
Sum(Metric) AS Metric
FROM TABLE_1
GROUP BY ID, DATEPART(qq,DATEADD(month, -15, [Month])), DATEPART(yy,DATEADD(month, -15, [Month]))
假设您的 table 季度数据如下所示:
CREATE TABLE QtrData(
ID INT NULL,
Qtr INT NULL,
Yr INT NULL,
Metric INT NULL
)
这个程序可以满足您的需求:
CREATE PROC dbo.spInsertQuarterlyData
@Dt datetime
AS
DECLARE @CurrQtrDt DATETIME
DECLARE @RangeStartDt DATETIME
DECLARE @RangeEndDt DATETIME
SELECT @CurrQtrDt = DATEADD(qq, DATEDIFF(qq, 0, @Dt), 0)
SELECT @RangeStartDt = DATEADD(mm,-15,@CurrQtrDt)
SELECT @RangeEndDt = DATEADD(dd,-1,DATEADD(mm,-3,@CurrQtrDt))
INSERT INTO QtrData( ID, Qtr, Yr, Metric )
SELECT
ID,
DATEPART(qq,@CurrQtrDt)-1,
DATEPART(yyyy,@CurrQtrDt),
SUM(Metric)
FROM Table_1
WHERE [Month] BETWEEN @RangeStartDt AND @RangeEndDt
GROUP BY ID
然后您将安排一个 SQL 作业每季度执行一次此过程,将 GETDATE()
作为参数传入。
要使用初始问题陈述中的历史数据填充 table,最简单的方法是调用此过程循环遍历历史季度,如下所示:
DECLARE @Dt datetime
SET @dt = '1/1/2011'
WHILE @dt < GETDATE()
BEGIN
EXEC dbo.spInsertQuarterlyData @dt
SET @dt = DATEADD(mm,3,@Dt)
END