2013-06-19 53 views
1

此示例中的第六個記錄是從我的CTE輸出丟失;我猜是因爲它只出現過一次?有沒有辦法讓它出現?如果這是一個愚蠢的問題,我很抱歉,我只是在CTE附近找到我的頭。CTE沒有生成我期待的內容?

CREATE TABLE #T (MONTH INT, YEAR INT, CC VARCHAR(4), CO_CC VARCHAR(7), VALUE INT) 

INSERT INTO #T VALUES (1, 2011, '0000', 'P1-0000', 10) 
INSERT INTO #T VALUES (2, 2011, '0000', 'P1-0000', 20) 
INSERT INTO #T VALUES (3, 2011, '0000', 'P1-0000', 30) 
INSERT INTO #T VALUES (4, 2011, '0000', 'P1-0000', 40) 
INSERT INTO #T VALUES (5, 2011, '0000', 'P1-0000', 50) 
INSERT INTO #T VALUES (5, 2011, '0017', 'P1-0017', 50) 
INSERT INTO #T VALUES (1, 2012, '0000', 'P1-0000', 10) 
INSERT INTO #T VALUES (2, 2012, '0000', 'P1-0000', 20) 
INSERT INTO #T VALUES (3, 2012, '0000', 'P1-0000', 30) 
INSERT INTO #T VALUES (4, 2012, '0000', 'P1-0000', 40) 
INSERT INTO #T VALUES (5, 2012, '0000', 'P1-0000', 50) 
INSERT INTO #T VALUES (1, 2011, '0006', 'P1-0006', 10) 
INSERT INTO #T VALUES (2, 2011, '0006', 'P1-0006', 20) 
INSERT INTO #T VALUES (3, 2011, '0006', 'P1-0006', 30) 
INSERT INTO #T VALUES (4, 2011, '0006', 'P1-0006', 40) 
INSERT INTO #T VALUES (5, 2011, '0006', 'P1-0006', 50) 
INSERT INTO #T VALUES (1, 2012, '0006', 'P1-0006', 10) 
INSERT INTO #T VALUES (2, 2012, '0006', 'P1-0006', 20) 
INSERT INTO #T VALUES (3, 2012, '0006', 'P1-0006', 30) 
INSERT INTO #T VALUES (4, 2012, '0006', 'P1-0006', 40) 
INSERT INTO #T VALUES (5, 2012, '0006', 'P1-0006', 50) 

GO 

WITH TEST 
AS 
(SELECT *, VALUE AS RUNNING_SUM FROM #T WHERE MONTH = 1 
UNION ALL 
SELECT w.*, w.VALUE + t.RUNNING_SUM FROM #T w 
INNER JOIN TEST t 
ON w.MONTH = t.MONTH + 1 
AND w.YEAR = t.YEAR 
AND w.CC = t.CC 
AND w.CO_CC = t.CO_CC 
WHERE w.MONTH > 1) 

SELECT * FROM TEST ORDER BY YEAR, MONTH OPTION (MAXRECURSION 0) 

DROP TABLE #T 

另外,如果我宣佈值爲DECIMAL(15,2)的CTE翻倒有關錨和遞歸類型是不兼容的一些錯誤?

回答

3

好吧,你缺少的行,因爲你JOIN條件:

INNER JOIN TEST t 
ON w.MONTH = t.MONTH + 1 
AND w.YEAR = t.YEAR 
AND w.CC = t.CC 
AND w.CO_CC = t.CO_CC 

所以,你說你需要下個月行(雖然這不會對工作月),上同年與相同CC。該特定行的值爲CC'0017',這在上個月不存在,因此它不會出現在您的遞歸CTE上。至於不兼容的問題,我不知道到底whay發生這種情況,但如果你使用第二SELECT明確的轉換,那麼就沒有問題:

SELECT w.*, CAST(w.VALUE + t.RUNNING_SUM AS DECIMAL(15,2)) 

UPDATE

所以作爲馬丁·史密斯在評論說,對於不兼容問題的原因是,CTE根據您的第一SELECT定義的列數據類型:

SELECT *, VALUE AS RUNNING_SUM 

所以,RUNNING_SUM將是一個DECIMAL(15,2)。關於你的第二選擇,該列來源於此計算:

w.VALUE + t.RUNNING_SUM 

由於兩個列DECIMAL(15,2),那麼結果是DECIMAL(16,2),根據this,所以兩列是不兼容的,因此,一個明確CAST需要。

+1

(15,2)+(15,2)=(16,2)'。這是[記錄在這裏](http://msdn.microsoft.com/en-us/library/ms190476.aspx) –

+0

@MartinSmith感謝您的解釋!,我不知道 – Lamak

3

你的WHERE條件被排除了線路,因爲從來沒有MONTH = 1,CC = '0017'

而是用月= 1開始的,你可以使用一個ROW_NUMBER OVER (PARTITION BY CC,YEAR ORDER BY MONTH)識別的第一個月。

+0

很好的回答,我同意。 –

1

第六個記錄永遠不會到來,因爲在UNION ALL當你與W.MONTH與實際表=#T.MONTH + 1 = w.YEAR t.YEAR AND w.CC = t.CC 加入CTE AND w.CO_CC = t.CO_CC 這意味着第4個月加入第5個月和第2011年以及第4個CC(0000)=第5個CC(0017),而不是第4個月CO_CC(P1-0000)=第5個月CO_CC(P1-0017)這又是不正確的。這就是第六行不會到來的原因。我希望你現在清楚。

相關問題