XQuery提取XML节点连续不同值 解决全局去重不符合需求问题
解决方案
你的问题核心是distinct-values()为全局去重逻辑,无法满足相邻去重需求,需要先按节点顺序比对相邻值,再拼接结果。以下为兼容SQL Server的实现方案:
实现代码
SELECT t.*, STUFF(( SELECT ' ' + v.val FROM ( -- 提取所有x节点的文本值,同时保留节点原始顺序编号 SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS rn, LTRIM(RTRIM(x.n.value('text()[1]','varchar(100)'))) AS val FROM t.TheParts.nodes('/x') AS x(n) ) AS v -- 仅保留第一个节点,或和前一个节点值不同的节点 WHERE v.rn = 1 OR v.val <> ( SELECT LTRIM(RTRIM(x2.n.value('text()[1]','varchar(100)'))) FROM t.TheParts.nodes('/x') AS x2(n) ORDER BY (SELECT 1) OFFSET v.rn - 2 ROWS FETCH NEXT 1 ROWS ONLY ) FOR XML PATH(''), TYPE ).value('.','varchar(max)'), 1, 1, '') AS Hierarchy FROM [Table] t
逻辑说明
- 先用
nodes()方法把XML中的所有<x>节点按原始顺序拆分,用ROW_NUMBER()给每个节点标注顺序序号,保证不会打乱XML原本的节点排列顺序 - 额外加了
LTRIM(RTRIM)处理节点文本前后的换行、空白字符,避免因为格式字符导致值比对错误 - 逐个比对当前节点和前一个序号节点的文本值,只有值不同或者是第一个节点的时候才保留
- 最后把过滤后的结果用空格拼接,用
STUFF去掉开头多余的空格,最终输出结果和你预期的AB AC AB完全一致
内容的提问来源于stack exchange,提问作者raider
相关产品推荐
相关产品推荐

