【发布时间】:2016-05-17 02:28:06
【问题描述】:
我不是 sql 和 t-sql 的新手,但过去我从未使用过递归查询 - 所有问题都通过 WHILE 或 CURSOR 解决。我刚收到 1 个问题 - 如何针对以下问题组织递归查询:我想使用某个分区中的最后一行数据进行操作。无法理解如何在分区的最后一级停止递归。
CREATE TABLE #temp
(i int
, s int
, v int);
INSERT INTO #temp
SELECT 1, 1, 10
UNION
SELECT 1, 2, 20
UNION
SELECT 2, 1, 5
UNION
SELECT 2, 2, 5
UNION
SELECT 2, 3, 2
WITH CTE AS
(
SELECT i
, s
, v
FROM #temp
WHERE s=1
UNION ALL
SELECT t.i
, t.s
, t.v + cte.v as new_v
FROM #temp t
INNER JOIN cte
ON (cte.i=t.i)
WHERE t.s>1
)
SELECT *
FROM cte
OPTION(MAXRECURSION 0)
我想得到 5 行结果:
我知道它可以通过 OUTER APPLY、JOINS、WHILE 或 CURSOR 方法解决。您能否分享任何功能让我了解如何使用递归 cte 查询获得相同的结果? SUM 函数只是一个例子 - 对于这个问题,递归查询是最好的方法,因为我将在大 CASE 中使用许多标量函数,这些函数将使用分区中最后一行的值和当前行分区的值。
谢谢。 对不起,我的英语水平不好。
如果我用下面的例子尝试同样的问题会正确吗?我想这需要正确地说明递归查询将以哪种顺序进行任何数据操作。下面的代码将帮助您理解我想要解决的问题:
CREATE TABLE #temp
(i_key int
, step int
, step_h int
, value int);
INSERT INTO #temp
SELECT 1, 1, NULL, 20
UNION
SELECT 1, 2, 1, 20
UNION
SELECT 2, 1, NULL, 10
UNION
SELECT 2, 2, 1, 10
UNION
SELECT 2, 3, 2, 5
WITH CTE AS
(
SELECT i_key
, step
, value
FROM #temp
WHERE step=1
--AND i_key=2
UNION ALL
SELECT t.i_key
, t.step
, CASE
WHEN cte.value - t.value <=0 THEN 0
ELSE cte.value - t.value
END as value
FROM #temp t
INNER JOIN cte
ON (cte.i_key=t.i_key
AND cte.step=t.step_h)
--WHERE t.step>1
)
SELECT *
FROM CTE
OPTION(MAXRECURSION 0)
解决这个问题总是需要父子结构吗? 所以我想它可以通过另一个连接来完成(没有父子列)。
AND cte.step=t.step-1
【问题讨论】:
-
顺便说一句,在你的输出示例中它应该是 7,或者你想要的基本上是当 s 列是 2 -> v1 +v2 时 3> v1+v2+v3?
-
i - 是键,s - 是步骤,v - 是值。为了简单理解,我写了这个例子,因为想用递归查询来实现这个结果。在递归中,我们得到所有关键示例的 1 步。在联合中,我们得到了操作当前键前行的所有其他步骤。
标签: sql sql-server tsql recursion ssms