将路径截断为降序子路径

问题描述 投票:0回答:1

我有一条看起来像这样的路径

Subdomain1>Subdomain2>Subdomain3>Subdomain3>Subdomain5

长度是可变的,也有可能为NULL。

我怎样才能创建 5 列这样

第 1 列显示根节点,第 2 列显示根节点和下一个节点,依此类推

因此在本例中第 3 列将是 Subdomain1>Subdomain2>Subdomain3

如果路径是

Subdomain1>Subdomain2

那么第 3、4 和 4 列将为空

路径是

Subdomain1>Subdomain2>Subdomain3>Subdomain3>Subdomain5>Subdomain6

那么第 5 列将是 Subdomain1>Subdomain2>Subdomain3>Subdomain3>Subdomain5

我们正在运行 SQL Server 2016

sql sql-server sql-server-2016
1个回答
0
投票

请尝试以下利用 SQL Server XML 和 XQuery 功能的解决方案。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY KEY, _path VARCHAR(256));
INSERT INTO @tbl (_path) VALUES
('Subdomain1>Subdomain2>Subdomain3>Subdomain3>Subdomain5'),
('Subdomain1>Subdomain2');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = '>';

SELECT *
    , col1 = IIF(cnt < 1, NULL, REPLACE(c.query('for $x in /root/r[position() le 1] 
        return data($x)').value('.', 'VARCHAR(256)'),SPACE(1),@separator))
    , col2 = IIF(cnt < 2, NULL, REPLACE(c.query('for $x in /root/r[position() le 2] 
        return data($x)').value('.', 'VARCHAR(256)'),SPACE(1),@separator))
    , col3 = IIF(cnt < 3, NULL, REPLACE(c.query('for $x in /root/r[position() le 3] 
        return data($x)').value('.', 'VARCHAR(256)'),SPACE(1),@separator))
    , col4 = IIF(cnt < 4, NULL, REPLACE(c.query('for $x in /root/r[position() le 4] 
        return data($x)').value('.', 'VARCHAR(256)'),SPACE(1),@separator))
    , col5 = IIF(cnt < 5, NULL, REPLACE(c.query('for $x in /root/r[position() le 5] 
        return data($x)').value('.', 'VARCHAR(256)'),SPACE(1),@separator))
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
      REPLACE(_path, @separator, ']]></r><r><![CDATA[') + 
      ']]></r></root>' AS XML)) AS t1(c)
CROSS APPLY (SELECT c.value('count(/root/r)', 'INT')) AS t2(cnt);

输出

id _路径 col1 col2 col3 col4 第5栏
1 子域名1>子域名2>子域名3>子域名3>子域名5 子域1 子域1>子域2 子域名1>子域名2>子域名3 子域名1>子域名2>子域名3>子域名3 子域名1>子域名2>子域名3>子域名3>子域名5
2 子域1>子域2 子域1 子域1>子域2
© www.soinside.com 2019 - 2024. All rights reserved.