sql server - 分数查询输出错误的月份

时间:2015-03-02 14:28:15

标签: sql-server

以下查询根据表ProviderValueCard中的条目计算每月得分。从2月到9月,该表每月有1个条目,但是此查询输出的结束日期为3月至10月的1个月。

我该如何纠正?要将EndDate分数输出更改为输入的月份而不是提前1个月?

    DECLARE @ProviderID INT = 1657, @Now DATETIME, @Months INT

    SELECT @Now = GETDATE(), @Months = 6;

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.EndDate ORDER BY Time_Stamp DESC) AS ordinal_position,
            a.ProviderID, 
            d.RowNum, 
            d.EndDate,
            [AdditionalReports] * 5 AS AdditionalReports,

            CASE [UniqueReportsNumQtr] WHEN 0 THEN 0
                                        WHEN 1 THEN 3.75
                                        WHEN 2 THEN 7.5
                                        WHEN 3 THEN 11.25
                                        WHEN 4 THEN 15
                                        ELSE 15
                                        END as [UniqueReportsNumQtr],

            CASE [SessionsProgress] WHEN 1 THEN 10
                                    WHEN 2 THEN 10
                                    WHEN 3 THEN 20
                                    WHEN 4 THEN 20
                                    WHEN 5 THEN 30
                                    ELSE 0
                                    END as [SessionsProgress],
            CASE  WHEN b.ProviderID IS NULL AND
                       RelatedID 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                
            LEFT OUTER JOIN PROVIDERS ON a.ProviderID = RelatedID           
             WHERE a.ProviderID = @ProviderID OR RelatedID = @ProviderID AND GroupID = 2             
            )
        SELECT ProviderID, RowNum, EndDate, (AdditionalReports + [UniqueReportsNumQtr] + [SessionsProgress] + [SubscriptionExists] ) AS TotalScore
        FROM main_cte
        WHERE ordinal_position = 1
        ORDER BY RowNum

当前输出

    ProviderID  RowNum      EndDate                 TotalScore
----------- ----------- ----------------------- ---------------------------------------
1657        1           2015-03-02 08:23:22.097 55.00
1657        2           2015-02-02 08:23:22.097 55.00
1657        3           2015-01-02 08:23:22.097 55.00
1657        4           2014-12-02 08:23:22.097 55.00
1657        5           2014-11-02 08:23:22.097 58.75
1657        6           2014-10-02 08:23:22.097 58.75

ProviderID 1657的ProviderValueCard条目 http://i.imgur.com/9yTJEqr.png

enter image description here

1 个答案:

答案 0 :(得分:1)

这是一个非常长的查询。我有个建议。可能会有更多。

尝试更改

WHERE
  a.ProviderID = @ProviderID OR RelatedID = @ProviderID AND GroupID = 2   

WHERE
  (a.ProviderID = @ProviderID OR RelatedID = @ProviderID) AND GroupID = 2  

我注意到另一个问题。我认为你想在你的小组中整整几个月。这也需要在INNER JOIN子句中进行一些小改动 - 我将整个查询排除在外:

WITH date_range_cte AS 
(
  SELECT 1 AS RowNum, DATEADD(mm, datediff(month 32, @Now), 0) AS StartDate, DATEADD(month, datediff(mm, 0, @Now), 0) AS EndDate
  UNION ALL
  SELECT d.RowNum + 1 AS RowNum, DATEADD(month,-1, StartDate) AS StartDate, DATEADD(month,-1, 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.EndDate ORDER BY Time_Stamp DESC) AS ordinal_position,
        a.ProviderID, 
        d.RowNum, 
        d.EndDate,
        [AdditionalReports] * 5 AS AdditionalReports,

        CASE [UniqueReportsNumQtr] WHEN 0 THEN 0
                                    WHEN 1 THEN 3.75
                                    WHEN 2 THEN 7.5
                                    WHEN 3 THEN 11.25
                                    WHEN 4 THEN 15
                                    ELSE 15
                                    END as [UniqueReportsNumQtr],

        CASE [SessionsProgress] WHEN 1 THEN 10
                                WHEN 2 THEN 10
                                WHEN 3 THEN 20
                                WHEN 4 THEN 20
                                WHEN 5 THEN 30
                                ELSE 0
                                END as [SessionsProgress],
        CASE  WHEN b.ProviderID IS NULL AND
                   RelatedID 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                
        LEFT OUTER JOIN PROVIDERS ON a.ProviderID = RelatedID           
        WHERE
          (a.ProviderID = @ProviderID OR RelatedID = @ProviderID) AND GroupID = 2
    )
    SELECT ProviderID, RowNum, EndDate, (AdditionalReports + [UniqueReportsNumQtr] + [SessionsProgress] + [SubscriptionExists] ) AS TotalScore
    FROM main_cte
    WHERE ordinal_position = 1
    ORDER BY RowNum