2010-08-16 74 views
2

這一個讓我快速堅持。用IF語句條件更新表中的每一行

數據:

Month   Total   Impact Forecast 
------------------------------------------------ 
2010-04-01 45792.0000 1.0000 NULL 
2010-05-01 51789.0000 1.0000 NULL 
2010-06-01 58228.0000 1.0000 NULL 
2010-07-01 52956.5217 1.0000 NULL 
2010-08-01 53600.4700 0.8810 NULL 
2010-09-01 54257.8784 1.1838 NULL 
2010-10-01 55134.0669 1.0000 NULL 

現在我想要做的是遍歷表的當前內容和IF語句如下使用條件更新預測列:

If Impact = 1.0000 then forecast = (current month) total * Impact 
If Impact < 1.0000 then forecast = (month -1) total * Impact 
If Impact > 1.0000 then forecast = (month -2) total * Impact 

我沒有想到使用CASE聲明,儘管使用以前的日期計算預測難倒了我,我認爲我需要利用一段時間的聲明和RBAR。

非常感謝。

回答

1

如何:

UPDATE [Table] 
SET 
    [Forecast] = [Impact] * CASE 
     WHEN [Impact] = 1.0000 THEN 
     (
      SELECT 
       [InnerTable].[Total] 
      FROM [Table] AS [InnerTable] 
      WHERE [InnerTable].[Month] = [Table].[Month] 
     ) 
     WHEN [Impact] < 1.0000 THEN 
     (
      SELECT 
       [InnerTable].[Total] 
      FROM [Table] AS [InnerTable] 
      WHERE [InnerTable].[Month] = DATEADD(month, -1, [Table].[Month]) 
     ) 
     ELSE 
     (
      SELECT 
       [InnerTable].[Total] 
      FROM [Table] AS [InnerTable] 
      WHERE [InnerTable].[Month] = DATEADD(month, -2, [Table].[Month]) 
     ) 
    END  
FROM [Table] 
+0

產生了錯誤的結果,其中Month是2010-08-01,2010-09-01和2010-10-01 – 2010-08-16 13:21:32

+0

@Daniel:我認爲'SET [Forecast] = CASE'應該是'SET [Forecast] = [影響] * CASE'。 (假設使用的影響應始終爲當月的影響,無論應使用哪個月的總數。) – 2010-08-16 13:37:47

+0

那麼如何設置預測=影響* CASE? – Icementhols 2010-08-16 13:52:47

1

你可以做一個花哨的聯合聲明,但我只用3個單獨的更新語句:

UPDATE table 
SET forecast = (current month) total * Impact 
WHERE Impact = 1.0000 
GO 
UPDATE table 
SET forecast = (month -1) total * Impact 
WHERE Impact < 1.0000 
GO 
UPDATE table 
SET forecast = (month -2) total * Impact 
WHERE Impact > 1.0000 
GO 
+0

關鍵字'current'附近的語法錯誤; 'total'附近語法不正確。 'total'附近語法不正確。 – 2010-08-16 13:14:45

+0

對不起,那部分是僞代碼,直接從問題中複製而來。我以爲你只是擔心IF的語法,但我現在可以看到,你必須從其他行中提取值,這是非常困難的。 – BradC 2010-08-16 13:55:33

3

試試這個:

DECLARE @YourTable table (MonthOf datetime, TotalOf numeric(9,4), Impact numeric(9,4), forecast numeric(9,4)) 

INSERT @YourTable VALUES('2010-04-01', 45792.0000, 1.0000, NULL) 
INSERT @YourTable VALUES('2010-05-01', 51789.0000, 1.0000, NULL) 
INSERT @YourTable VALUES('2010-06-01', 58228.0000, 1.0000, NULL) 
INSERT @YourTable VALUES('2010-07-01', 52956.5217, 1.0000, NULL) 
INSERT @YourTable VALUES('2010-08-01', 53600.4700, 0.8810, NULL) 
INSERT @YourTable VALUES('2010-09-01', 54257.8784, 1.1838, NULL) 
INSERT @YourTable VALUES('2010-10-01', 55134.0669, 1.0000, NULL) 

;WITH MonthValues AS 
(
    SELECT 
     DATEADD(month,DATEDIFF(month,0,MonthOf),0) AS MonthYear 
      ,SUM(TotalOf) TotalOf 
    FROM @YourTable 
    GROUP BY DATEADD(month,DATEDIFF(month,0,MonthOf),0) 
) 
UPDATE y 
    SET Forecast=CASE 
        WHEN Impact = 1.0000 then m1.TotalOf * Impact 
        WHEN Impact < 1.0000 then m2.TotalOf * Impact 
        WHEN Impact > 1.0000 then m3.TotalOf * Impact 
       END 
    FROM @YourTable      y 
     LEFT OUTER JOIN MonthValues m1 ON DATEADD(month,DATEDIFF(month,0,y.MonthOf),0)=m1.MonthYear 
     LEFT OUTER JOIN MonthValues m2 ON DATEADD(month,-1,DATEADD(month,DATEDIFF(month,0,y.MonthOf),0))=m2.MonthYear 
     LEFT OUTER JOIN MonthValues m3 ON DATEADD(month,-2,DATEADD(month,DATEDIFF(month,0,y.MonthOf),0))=m3.MonthYear 

SELECT * FROM @YourTable 

OUTPUT:

MonthOf     TotalOf  Impact forecast 
----------------------- ----------- ------- ----------- 
2010-04-01 00:00:00.000 45792.0000 1.0000 45792.0000 
2010-05-01 00:00:00.000 51789.0000 1.0000 51789.0000 
2010-06-01 00:00:00.000 58228.0000 1.0000 58228.0000 
2010-07-01 00:00:00.000 52956.5217 1.0000 52956.5217 
2010-08-01 00:00:00.000 53600.4700 0.8810 46654.6956 
2010-09-01 00:00:00.000 54257.8784 1.1838 62689.9304 
2010-10-01 00:00:00.000 55134.0669 1.0000 55134.0669 

(7 row(s) affected)