这个递归 CTE 有啥问题,更重要的是,我无法理解啥一般概念?

     2023-04-14     280

关键词:

【中文标题】这个递归 CTE 有啥问题,更重要的是,我无法理解啥一般概念?【英文标题】:What's wrong with this recursive CTE and more importantly, what general concept am I failing to comprehend?这个递归 CTE 有什么问题,更重要的是,我无法理解什么一般概念? 【发布时间】:2015-09-04 20:05:16 【问题描述】:

好的,我正在研究将一组记录转换为分隔列表的问题。这是一个老问题,有几种方法,在很多情况下,我什至不应该在数据库中这样做。但是,在 this 的情况下,我想并且我想使用递归 CTE。

正如我的标题所暗示的那样,我对真正掌握这个概念的困难感到沮丧。过去,我用书籍或互联网帖子中的代码 sn-ps 解决了这个问题,并对其进行了改编并让它们工作。但这总是很难,而且我并没有真正掌握这项技术。我寻找了该技术的一个非常基本的实现,并得到了我用作模型的答案:https://***.com/a/9726839/13748

所以现在,我有这个临时表#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 列值列表。我正在尝试用这个(以及一堆令人沮丧的排列)来做到这一点:

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;

返回这个:

id  POs
--- -----------
1   374534-6988

我知道你们中的一个人将能够在接下来的八分钟内指出代码错误。但我希望有人可以重新定义它正在做什么,这样我就可以真正理解它并将它从这次遭遇中带走,作为未来使用的工具。

也许一旦发生这种情况,我就可以自己回答这个问题了,但是这个查询能否同时处理 PO 和 SO 列,产生两个字段,每个字段都是逗号分隔的列表两个各自的列?

感谢您的宝贵时间!

【问题讨论】:

您说您正在尝试创建以逗号分隔的值列表。与使用递归 cte 相比,您可以更容易地做到这一点。您可以使用 FOR XML 来更轻松、更快速地完成此操作。 sqlservercentral.com/articles/comma+separated+list/71700 @SeanLange - OP 似乎知道不同的方法,但声明“在这种情况下,我想要,并且我想要使用递归 CTE。” 但是递归 cte 是一种效率低下的工具。仅仅因为它可以这样做并不意味着它应该这样做。 没错,我过去也为此使用过 FOR XML PATH。 @SeanLange 当您说“更快”时,您是指更快地编写代码还是更快地执行代码? 写起来肯定更快,根据我的经验,执行起来也更快。当然要看深度。 :) 【参考方案1】:

p2.id + 1 = POlists.id 应该是 p2.id - 1 = POlists.id 唯一的错误是代数。

您的第一个 id 是 1。没有行与 p2.id + 1 =1 一样,因为您没有 id 为 0 的行,所以它停在那里。

虽然p2.id = POlists.id + 1 可能会允许在递归部分进行索引查找。

您可能希望在其中设置一个级别列来返回完整的字符串。

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;

【讨论】:

哇!我只是对此视而不见。那么,关于级别,为什么我不能只取与最高 ID 关联的结果呢?就像SELECT TOP 1 POs FROM POlists ORDER BY id DESC 我的意思是,它现在可以工作,但是还有其他一些我没有想到的情况吗?我认为不是因为我在执行此查询之前在该临时表中创建了 ID。 @clweeks - 好点 - 其余代码依赖于 id 无论如何都是连续的,所以你不妨使用它。从技术上讲,标识列不能保证顺序,但对于临时表,如果您在单个语句中插入,我从未见过差距。

递归 CTE 如何逐行运行?

】递归CTE如何逐行运行?【英文标题】:HowdoesaRecursiveCTErun,linebyline?【发布时间】:2010-07-0615:45:57【问题描述】:我认为我已经很好地掌握了递归CTE的格式,可以编写一个,但我仍然感到沮丧,因为我无法手动处理一个(假装自... 查看详情

防止递归 CTE 多次访问节点

...以下简单的DAG:1->2->3->4还有一个表格,#bar,描述这个(我使用的是SQLServer2005):parent_idchild_id122334//...otheredges,notconnectedtoth 查看详情

递归 CTE 存在性能问题,需要建议以优化查询

】递归CTE存在性能问题,需要建议以优化查询【英文标题】:RecursiveCTEhaveperformaceissue,needsuggestiontooptimizequery【发布时间】:2019-12-1308:52:36【问题描述】:我想从日志表中获取前5条记录,其中“批准日期”已更改为NULL,反之亦然... 查看详情

表数据子集上的递归 CTE

...录以及开始日期和结束日期之间的月份和年份。我创建了这个递归CTE查询来执行此操作,但它只返回我需要的子集中的一条记录。我的问题是如何编辑它,以便它在子集中的所有记录上运行递归CTE。 查看详情

投票有啥问题?

...发生了变化,然后运行一个任务,比如导入。我真的反对这个想法,我觉得利用Remoting、WCF等可用的技术比轮询要好得多。但是,我想找出为什么其他人更喜欢一种方法而不是另一种方法的原因,更重要的是,我如何才能 查看详情

如何通过回溯和递归解决数独?

...发布时间】:2016-02-0714:58:11【问题描述】:我之所以创建这个新线程,而不是仅仅阅读之前给出的这个特定问题的答案,是因为我觉得我只是不完全理解它背后的整个想法。我似乎无法理解整个回溯的概念。所以我需要充分理解... 查看详情

将 SQL Server 中的递归 CTE 转换为 netezza

...归CTE转换为netezza!netezza会支持递归CTE吗?谁能帮我解决这个问题?提前致谢,马尼拉蒂南。【问题讨论】:【参考方案1】:从7.2版开始,Netezza不支持递 查看详情

如何正确应用递归 CTE?

】如何正确应用递归CTE?【英文标题】:HowtoproperlyapplyrecursiveCTE?【发布时间】:2019-09-3021:28:01【问题描述】:我有一张表格,其中包含患者就诊的情况。我正在尝试标记访问“begin_date”与之前的访问“end_date”重叠90天的访问。... 查看详情

在 CTE 中对日期范围内的列求和?

...mmingacolumnoveradaterangeinaCTE?【发布时间】:2016-04-1216:51:33【问题描述】:我正在尝试对某个日期范围内的某个列求和。更重要的是我希望这是一个CTE,因为我必须多次使用它作为更大查询的一部分。由于它是CTE,它必须具有日期列... 查看详情

我似乎无法理解我的代码有啥问题,我无法获得输出

】我似乎无法理解我的代码有啥问题,我无法获得输出【英文标题】:Icantseemtogetwhatswrongwithmycode,Icantgettheoutput我似乎无法理解我的代码有什么问题,我无法获得输出【发布时间】:2019-11-2119:42:52【问题描述】:我一直在使用三... 查看详情

递归 CTE 通过多个级别更新父记录

】递归CTE通过多个级别更新父记录【英文标题】:RecursiveCTEtoupdateparentrecordsthroughmultiplelevels【发布时间】:2015-10-2900:03:18【问题描述】:CTE是否会在下一次递归中使用作为CTE一部分更新的数据?我正在尝试这种CTE,因为在WHILE循... 查看详情

递归 CTE - row_number() 聚合

】递归CTE-row_number()聚合【英文标题】:CTEwithrecursion-row_number()aggregated【发布时间】:2014-03-0111:59:47【问题描述】:我有一个具有父/子关系的表以及一个引用自身的创建日期列。我想显示节点上最近的“活动”排序的每个父记录... 查看详情

这个递归算法有啥问题?

】这个递归算法有啥问题?【英文标题】:What\'swronginthisrecursivealgorithm?这个递归算法有什么问题?【发布时间】:2016-06-1514:49:30【问题描述】:问题陈述:N元素排列是集合1,2,...,n中不同数字的N元素序列。例如,序列2,1,4,5,3是一... 查看详情

我使用 dislousreGroup 作为递归,但视图更新无法正常工作。有啥办法吗?

】我使用dislousreGroup作为递归,但视图更新无法正常工作。有啥办法吗?【英文标题】:IusedisclousreGroupasrecursion,buttheviewupdatedoesn\'tworkproperly.Isthereanyway?我使用dislousreGroup作为递归,但视图更新无法正常工作。有什么办法吗?【发... 查看详情

CTE递归获取树层次结构

】CTE递归获取树层次结构【英文标题】:CTERecursiontogettreehierarchy【发布时间】:2013-08-0900:57:18【问题描述】:我需要以特定方式获得树的有序层次结构。有问题的表看起来有点像这样(所有ID字段都是唯一标识符,为了举例,我... 查看详情

UI-Test 和 Rest 有啥区别?

...2018-01-2113:48:58【问题描述】:我在采访一些公司时遇到了这个问题。我觉得我不能很好地回答这个问题。但是,根据我的理解:UI级别测试更多的是关于最终用户将看到的内容,并且更适合用于验收测试。Rest测试有利于性能测试... 查看详情

在 css 中有啥比 !important 更重要的吗?

】在css中有啥比!important更重要的吗?【英文标题】:Isthereanythingmoreimportantthan!importantincss?在css中有什么比!important更重要的吗?【发布时间】:2011-10-2021:33:03【问题描述】:似乎我的wordpress主题默认添加了带有!important条件的字体... 查看详情

分区上的递归 CTE 或 ROW_NUMBER?

】分区上的递归CTE或ROW_NUMBER?【英文标题】:recursiveCTEorROW_NUMBERoverpartition?【发布时间】:2018-05-2111:35:08【问题描述】:您好,下面是一个小示例,我正在尝试找到一种方法来重置基于CDO_OP_REFERRAL_UNIQUE_ID的ATTENDED_OR_DID_NOT_ATTEND的... 查看详情