Sql 如何将XML行转换为列
我已经看到了一些关于如何将行转换为列的答案,但是这些答案对于这些问题来说非常具体,并且很难转换为我自己的解决方案 数据开始时是一个varchar,但我将其转换为XML,因为我认为这样将其转换为列会更容易Sql 如何将XML行转换为列,sql,sql-server,xml,Sql,Sql Server,Xml,我已经看到了一些关于如何将行转换为列的答案,但是这些答案对于这些问题来说非常具体,并且很难转换为我自己的解决方案 数据开始时是一个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&
-- 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)
这将返回如下结果:;但是,我现在需要将每一行转换为一列
我已经尝试过使用pivot和DynamicSQL的变体,但还没走多远。当行数未知时,如何将每一行转换为一列
参考文献。
参考这次我很抱歉要自己动手:。。。以下查询接收HTML,将其转换为XML,定义列名,并在执行之前写入动态SQL 最终结果是:
SQL用于结构化数据。这需要知道列的数量、名称和数据类型。数据库引擎依赖于此。尝试执行您描述的操作会打破SQL范式。也许你在用错误的语言工作?或者,也许有更好的模式来解决您的实际问题?告诉我们你为什么要这样做,你将如何处理这些数据,也许我们可以指导你。但是,现在看来,你正试图迫使自己走上一条死胡同。虽然我完全同意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;