1

我的 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

另外,如果我将 VALUE 声明为 DECIMAL (15, 2),CTE 会因锚点和递归类型不兼容的一些错误而崩溃?

4

3 回答 3

3

您的 WHERE 标准不包括该行,因为 MONTH never = 1 for CC = '0017'

ROW_NUMBER OVER (PARTITION BY CC,YEAR ORDER BY MONTH) 您可以使用 a来标识第一个月,而不是从 MONTH = 1 开始。

于 2013-06-19T18:08:43.763 回答
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

因此,您是说您需要下个月的行(尽管这不适用于 12 月),在同一年和同一CC. 该特定行的值为CCof '0017',上个月不存在,因此它不会出现在您的递归 CTE 中。至于不兼容问题,我不确定这是为什么发生的,但是如果您在 second 上使用显式转换SELECT,那么就没有问题:

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

更新

因此,正如 Martin Smith 在评论中所说,不兼容问题的原因是 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

于 2013-06-19T18:10:10.990 回答
1

第六条记录永远不会出现,因为在 UNION ALL 中,当您在 W.MONTH = #T.MONTH + 1 AND w.YEAR = t.YEAR AND w.CC = t.CC AND w.CO_CC = t 上加入 CTE 时.CO_CC 这意味着第 4 个月加入了第 5 个月和 2011 年,第 4 个月 CC (0000) = 第 5 个月 CC (0017) 不是,第 4 个月 CO_CC (P1-0000) = 第 5 个月 CO_CC (P1-0017)又不是真的。这就是第六排不来的原因。我希望你现在清楚了。

于 2013-06-19T18:17:38.733 回答