2015-03-02 22 views
0

以下查詢根據表ProviderValueCard中的條目計算每月的分數。該表有每個月從二月回九月然而這查詢輸出從三月的結束日期提前1個月回至10月sql server - 分數查詢輸出錯誤的月份

我怎樣才能解決這個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 

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

enter image description here

+0

你的問題不是很清楚。但是爲什麼你在表中使用'@ now'而不是輸入時間戳(或日期)列呢? – Andrew 2015-03-02 14:44:20

+0

你用DATEADD(毫米,-d.RowNum,@現在)AS結束日期,其中現在= GETDATE()是當前的日期 - 3月當月已 – rba 2015-03-02 14:46:16

+0

不會修復邏輯,但[請拼出'MONTH',而不是模棱兩可的速記如'mm'](http://sqlblog.com/blogs/aaron_bertrand/archive/2011/09/20/bad-habits-to-kick-using-shorthand-with-date-time-operations.aspx)。 – 2015-03-02 14:53:07

回答

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