这个递归 CTE 有什么问题,更重要的是,我没有理解什么一般概念?
What's wrong with this recursive CTE and more importantly, what general concept am I failing to comprehend?
好的,我正在研究将一组记录转换为分隔列表的问题。这是一个老问题,有几种方法,在很多情况下,我什至不应该在数据库中这样做。但是,在 this 的情况下,我想要,并且我想要使用递归 CTE。
正如我的标题所暗示的那样,我对真正掌握这个概念的困难感到沮丧。过去,我用书籍或互联网帖子中的代码片段解决了这个问题,并对它们进行了调整并使它们起作用。但这总是很难,而且我并没有真正掌握这项技术。我寻找了该技术的一个非常基本的实现,并找到了我用作模型的答案:
所以现在,我有这个临时 table #POSO,内容如下:
id inspectionLogKey PO SO
--- ---------------- ------------- ---------
1 7 374534-6988 SO37047
2 7 374534-5464 SO34110
3 7 374534-7135 SO37377
4 7 374534-5284 SO33863
5 7 374534-6710 SO36506
6 7 374534-5084 SO33565
根据这些数据,我想生成 PO 列值的 comma-delimited 列表。我正在尝试用这个(以及一堆令人沮丧的排列)来做到这一点:
WITH POlists(id,POs) AS
(
SELECT p1.id, CONVERT(VARCHAR(MAX),p1.PO) as POs --anchor
FROM #POSO p1
WHERE p1.id = 1
UNION ALL
SELECT p2.id, POs + ',' + p2.PO --recursive
FROM #POSO p2
join POlists ON p2.id + 1 = POlists.id
)
SELECT * FROM POlists;
哪个returns这个:
id POs
--- -----------
1 374534-6988
我知道你们中的一个人将能够在接下来的八分钟内指出代码错误。但我希望有人可以重新构建它正在做的事情,这样我就可以真正理解它并将它从这次相遇中拿走作为未来使用的工具。
也许一旦发生这种情况,我就可以自己回答这个问题了,但是这个查询能否同时处理 PO 和 SO 列,生成两个字段,每个字段都是 comma-delimited两个相应列的列表?
感谢您的宝贵时间!
p2.id + 1 = POlists.id
应该是p2.id - 1 = POlists.id
唯一的错误是代数。
您的第一个 ID 是 1。没有行 p2.id + 1 =1
因为您没有 ID 为 0 的行,所以它就停在那里。
虽然 p2.id = POlists.id + 1
最好允许在递归部分进行索引查找。
并且您可能希望其中的级别列仅 return 完成的字符串。
WITH POlists(id,POs, Lvl) AS
(
SELECT p1.id, CONVERT(VARCHAR(MAX),p1.PO) as POs, 0 AS Lvl
FROM #POSO p1
WHERE p1.id = 1
UNION ALL
SELECT p2.id, POs + ',' + p2.PO, Lvl + 1
FROM #POSO p2
join POlists ON p2.id = POlists.id + 1
)
SELECT TOP 1 *
FROM POlists
ORDER BY Lvl DESC;
好的,我正在研究将一组记录转换为分隔列表的问题。这是一个老问题,有几种方法,在很多情况下,我什至不应该在数据库中这样做。但是,在 this 的情况下,我想要,并且我想要使用递归 CTE。
正如我的标题所暗示的那样,我对真正掌握这个概念的困难感到沮丧。过去,我用书籍或互联网帖子中的代码片段解决了这个问题,并对它们进行了调整并使它们起作用。但这总是很难,而且我并没有真正掌握这项技术。我寻找了该技术的一个非常基本的实现,并找到了我用作模型的答案:
所以现在,我有这个临时 table #POSO,内容如下:
id inspectionLogKey PO SO
--- ---------------- ------------- ---------
1 7 374534-6988 SO37047
2 7 374534-5464 SO34110
3 7 374534-7135 SO37377
4 7 374534-5284 SO33863
5 7 374534-6710 SO36506
6 7 374534-5084 SO33565
根据这些数据,我想生成 PO 列值的 comma-delimited 列表。我正在尝试用这个(以及一堆令人沮丧的排列)来做到这一点:
WITH POlists(id,POs) AS
(
SELECT p1.id, CONVERT(VARCHAR(MAX),p1.PO) as POs --anchor
FROM #POSO p1
WHERE p1.id = 1
UNION ALL
SELECT p2.id, POs + ',' + p2.PO --recursive
FROM #POSO p2
join POlists ON p2.id + 1 = POlists.id
)
SELECT * FROM POlists;
哪个returns这个:
id POs
--- -----------
1 374534-6988
我知道你们中的一个人将能够在接下来的八分钟内指出代码错误。但我希望有人可以重新构建它正在做的事情,这样我就可以真正理解它并将它从这次相遇中拿走作为未来使用的工具。
也许一旦发生这种情况,我就可以自己回答这个问题了,但是这个查询能否同时处理 PO 和 SO 列,生成两个字段,每个字段都是 comma-delimited两个相应列的列表?
感谢您的宝贵时间!
p2.id + 1 = POlists.id
应该是p2.id - 1 = POlists.id
唯一的错误是代数。
您的第一个 ID 是 1。没有行 p2.id + 1 =1
因为您没有 ID 为 0 的行,所以它就停在那里。
虽然 p2.id = POlists.id + 1
最好允许在递归部分进行索引查找。
并且您可能希望其中的级别列仅 return 完成的字符串。
WITH POlists(id,POs, Lvl) AS
(
SELECT p1.id, CONVERT(VARCHAR(MAX),p1.PO) as POs, 0 AS Lvl
FROM #POSO p1
WHERE p1.id = 1
UNION ALL
SELECT p2.id, POs + ',' + p2.PO, Lvl + 1
FROM #POSO p2
join POlists ON p2.id = POlists.id + 1
)
SELECT TOP 1 *
FROM POlists
ORDER BY Lvl DESC;