我已经看到了一些有关如何将行转换为列的答案,但是它们是特定于问题的,因此我很难转换成自己的解决方案。
数据以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?
答案 0 :(得分:1)
这次我正准备好帮助自己:)...下面的查询接收HTML,将其转换为XML,定义列名并在执行动态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;