SQL Server:如何返回过去6个月的值

时间:2014-09-04 17:21:39

标签: sql-server

我有一个查询,返回关于3列= 1的分数,然后返回第2表中是否存在ProviderID的分数。我需要能够使用列Time_Stamp每月返回6个月的分数,不包括当前月份。以下返回上个月的分数。如何包含剩余的5个月和ROW_NUMBER()个?

DECLARE @ProviderID int = '1717';

WITH cte as
(
    SELECT TOP 1 
       a.ProviderID, Time_Stamp,
       SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
       SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
       SUM(CASE WHEN [SurveyCompleted] = '1' THEN 30 ELSE 0 END) as SurveyCompleted,
       MAX(CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END) as SubscriptionExists
    FROM 
       ProviderValueCard a
    LEFT JOIN 
       SubscriptionsTV b ON a.ProviderID = b.ProviderID  
    WHERE 
       a.ProviderID = @ProviderID AND GroupID = 2
       AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND  DATEADD(DAY, -(DAY(GETDATE())), GETDATE())
    GROUP BY 
       Time_Stamp, a.ProviderID, event
    ORDER BY 
        event DESC, Time_Stamp DESC
)
SELECT 
   ProviderID, Time_Stamp, 
   (AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM 
   cte

以下是抓住前几个月的第一天/最后一天的方法:

2个月前:

DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 2, 0) as FirstD2monthsago,
        DATEADD(DAY, -DAY(GETDATE()), DATEADD(MONTH, -1, GETDATE())) AS last_day_2_months_ago

3个月前等:

DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 3, 0) as FirstD3monthsago,
        DATEADD(DAY, -DAY(GETDATE()), DATEADD(MONTH, -2, GETDATE())) AS last_day_3_months_ago

期望的输出

ProviderID  Time_Stamp              TotalScore  Row_Number
----------- ----------------------- -----------
1717        2014-08-29 12:11:17.610 70              1
1717        2014-07-29 12:11:17.610 95              2
1717        2014-06-29 12:11:17.610 100             3
1717        2014-05-29 12:11:17.610 70              4
1717        2014-04-29 12:11:17.610 70              5
1717                                                6

2 个答案:

答案 0 :(得分:2)

DECLARE @ProviderID INT, @Now DATETIME, @Months INT
SELECT @ProviderID  = 1717, @Now = GETDATE(), @Months = 5

WITH 
date_range_cte AS (
    SELECT 1 AS RowNum, DATEADD(mm,-1,@Now) AS StartDate, DATEADD(mm,0,@Now) AS EndDate
    UNION ALL
    SELECT d.RowNum + 1 AS RowNum, DATEADD(mm,(-d.RowNum - 1),@Now) AS StartDate, DATEADD(mm,-d.RowNum,@Now) AS EndDate
    FROM date_range_cte d
    WHERE d.RowNum + 1 <= @Months
    ),
    main_cte AS (
            SELECT 
            ROW_NUMBER() OVER (PARTITION BY a.ProviderID, d.RowNum, d.StartDate ORDER BY Time_Stamp DESC) AS ordinal_position,
            a.ProviderID, 
            d.RowNum, 
            d.StartDate,
            [AdditionalReports] * 5 AS AdditionalReports,
            [UniqueReportRequests] * 15 AS UniqueReportsRequests,
            [SurveyCompleted] * 30 as SurveyCompleted,
            CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END as SubscriptionExists
            FROM ProviderValueCard a
            INNER JOIN date_range_cte d ON d.StartDate < Time_Stamp AND Time_Stamp <= d.EndDate 
            LEFT OUTER JOIN SubscriptionsTV b ON a.ProviderID = b.ProviderID  
            WHERE a.ProviderID = @ProviderID AND GroupID = 2
            )  
        SELECT ProviderID, RowNum, StartDate, (AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
        FROM main_cte
        WHERE ordinal_position = 1
        ORDER BY RowNum

答案 1 :(得分:0)

以下是两种方式(伪代码):

1 - 按照您想要获得的每月的现有口碑。你需要改变的唯一一件就是这一行:

AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND  DATEADD(DAY, -(DAY(GETDATE())), GETDATE())

2个月前,您可以将其更改为:

AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 2, 0) AND  DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0)

以及其他几个月前的情况。

2 - 参考上面cte中的同一行,将其更改为-6以获取过去6个月的数据。然后在您的选择列表中包含MONTH(TimeStamp)列,并按其分组,以便在过去6个月内每月获得一行。