[英]SQL - Creating stored procedure to loop through dates to calculate a measure
Problem - I'm trying to create a stored procedure that will run quarterly to calculate a metric (in this case, a sum) over a moving year-long window of monthly historical data, where the calculation starts from three months prior to the first day of the quarter and looks back a year prior to that date. 问题-我正在尝试创建一个存储过程,该过程将每季度运行一次,以计算移动的长达一年的每月历史数据窗口中的指标(在这种情况下为总和),其中计算从第一个月的前三个月开始季度的一天,然后回溯该日期之前的一年。 So, when the procedure runs on 4/1/2015, I want to calculate the metric from 1/1/2014 through 12/31/2014.
因此,当程序在2015年4月1日运行时,我想计算从2014年1月1日到2014年12月31日的指标。 On 7/1/2015, I want to calculate the metric from 4/1/2014 through 3/31/2015.
我想在2015年7月1日计算从2014年4月1日到2015年3月31日的指标。 And on and on and on.
并不断。 (It will also have to include historical quarter-based calculations of the metric as well.)
(还必须包括该指标的基于历史季度的计算。)
Because this is an analysis that will be run regularly, I'm needing to automate the process, and my thought is that some kind of loop is appropriate. 因为这是将定期运行的分析,所以我需要使该过程自动化,并且我认为某种循环是合适的。 I'm new to programming in SQL - my experience is almost exclusively querying - and any help would be appreciated.
我是SQL编程的新手-我的经验几乎完全是查询-任何帮助将不胜感激。
As it stands, my data look like this (apologies for the length): 就目前而言,我的数据看起来像这样(对长度表示歉意):
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
It's easy enough to write a query to get the results for any one quarter (Q1 2012): 编写查询以获取任一季度(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
Output: 输出:
ID Quarter Year Metric
123456 01 2012 49
Writing a variant of this for every quarter of analysis is obviously inefficient (and wouldn't work anyway for what I'm trying to create), so the goal is to write some kind of loop to automate the process. 为每个季度的分析编写一个这样的变体显然是效率低下的(并且对于我要创建的东西还是不管用),因此目标是编写某种循环来使过程自动化。
The desired output would look like this: 所需的输出如下所示:
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
I'm stuck, and my lack of experience programming in SQL is proving to be a challenge. 我被困住了,缺乏对SQL编程的经验被证明是一个挑战。 Any suggestions on how to proceed?
有关如何进行的任何建议? Thanks in advance!
提前致谢!
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]))
Assuming your table for quarterly data looks like this: 假设您的季度数据表如下所示:
CREATE TABLE QtrData(
ID INT NULL,
Qtr INT NULL,
Yr INT NULL,
Metric INT NULL
)
This proc would satisfy your needs: 此过程将满足您的需求:
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
You would then schedule a SQL job to execute this proc quarterly, passing in GETDATE()
as a parameter. 然后,您将安排一个SQL作业按季度执行此proc,并传入
GETDATE()
作为参数。
To populate the table with the historical data from your initial problem statement, the simplest way would be to call this proc looping through historical quarters, like this: 要使用初始问题陈述中的历史数据填充表,最简单的方法是调用此proc遍历历史区域,如下所示:
DECLARE @Dt datetime
SET @dt = '1/1/2011'
WHILE @dt < GETDATE()
BEGIN
EXEC dbo.spInsertQuarterlyData @dt
SET @dt = DATEADD(mm,3,@Dt)
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.