【问题标题】:How to Convert XML Rows to Columns如何将 XML 行转换为列
【发布时间】:2018-10-03 23:45:16
【问题描述】:

我已经看到了一些关于如何将行转换为列的答案,但它们是针对问题的,而且我很难将它们转换为我自己的解决方案。

数据以 varchar 开始,但我将其转换为 XML,因为我认为以这种方式将其转换为列会更容易。

-- get xml
DECLARE @x XML

SET @x = '<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li>Fits the Genesis S-300 gas grill</li><li>Includes a heavy-duty electric motor</li><li>Counterbalance for smooth turning and less motor wear</li></ul>'

SELECT x.r.value('node()[1]','varchar(200)')
FROM @x.nodes('/ul/li') AS x(r)

这会返回如下结果;但是,我现在需要将每一行转换为一列。

我尝试过使用数据透视和动态 SQL 的变体,但还没有走多远。 如何将每一行转换为一列(当行数未知时)。

参考。 Convert Rows to columns using 'Pivot' in SQL Server 参考。 How to convert row values to columns with dynamic columns count?

【问题讨论】:

  • SQL 用于结构化数据。这涉及了解列的数量、它们的名称和数据类型。数据库引擎依赖于此。尝试执行您所描述的操作会破坏 SQL 范式。也许您正在使用错误的语言工作?或者,也许有更好的模式来尝试解决您的实际问题?告诉我们您为什么要这样做,您将如何处理这些数据,也许我们可以指导您。但是,现在,您似乎正试图强迫自己走上死胡同。
  • 虽然我完全同意这看起来像 sql 可能不是处理数据的最佳方式,但这是绝对可行的。您需要搜索动态数据透视表或动态交叉表。它已被询问和回答了数百次。事实上,您问题中的第二个链接详细说明了如何执行此操作。
  • 我想通了。很快发布解决方案

标签: sql sql-server xml


【解决方案1】:

这次我已经准备好帮助自己了 :) ...以下查询接收 HTML,将其转换为 XML,定义列名并在执行之前编写动态 SQL。

最终结果是:

DECLARE @x XML,
 @limit int = 4,
 @ItemId NVARCHAR(10) = '11158',
 @cols AS NVARCHAR(MAX),
 @query  AS NVARCHAR(MAX)

-- get xml
SELECT @x = '<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li>Fits the Genesis S-300 gas grill</li><li>Includes a heavy-duty electric motor</li><li>Counterbalance for smooth turning and less motor wear</li></ul>'

-- convert rows to columns
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from
                    (
                      SELECT top (@limit)
                        bar.value('local-name(.)','VARCHAR(12)') + cast(row_number() over(order by bar.value('./.','VARCHAR(10)') asc) as varchar(10)) as name,  
                        bar.value('./.','VARCHAR(255)') as value 
                        FROM
                        @x.nodes('/ul/*') AS foo(bar) 
                    ) d
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

-- create dynamic sql
set @query = '
            -- get xml
                DECLARE @x XML
                SELECT @x = ''<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li>Fits the Genesis S-300 gas grill</li><li>Includes a heavy-duty electric motor</li><li>Counterbalance for smooth turning and less motor wear</li></ul>''
            SELECT ' + @cols + ' 
             from 
             (
               SELECT
                bar.value(''local-name(.)'',''VARCHAR(12)'') + cast(row_number() over(order by bar.value(''./.'',''VARCHAR(10)'') asc) as varchar(10)) as name,  
                bar.value(''./.'',''VARCHAR(255)'') as value 
                FROM
                @x.nodes(''/ul/*'') AS foo(bar) 
            ) x
            pivot 
            (
                max(value)
                for name in (' + @cols + ')
            ) p '

execute sp_executesql @query;

【讨论】:

    猜你喜欢
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多