我有像这样的xml:
<root>
<item>
<Name>Pants</Name>
<Value>No</Value>
</item>
<item>
<Name>Other</Name>
<Value>Yes</Value>
</item>
</root>
<root>
<item>
<Name>Pants</Name>
<Value>Yes</Value>
</item>
<item>
<Name>Other</Name>
<Value>Yes</Value>
</item>
</root>
<root>
<item>
<Name>a</Name>
<Value>b</Value>
</item>
<item>
<Name>c</Name>
<Value>d</Value>
</item>
</root>
每个root
元素都存储在sql server数据库的一列中,我需要根据它创建列/行。我希望“名称”作为列名称和为该列填充的值。也可能并不总是有2个<item>
元素,可能会有更多或更少。
所以当我要求查询以上所有内容时,我想:
|other columns|Pants|Other|a|c|<-column names
|~~~~~~~~~~~~~|No |Yes | | |<-rows
|~~~~~~~~~~~~~|Yes |Yes | | |
|~~~~~~~~~~~~~| | |b|d|
这甚至可能吗?
答案 0 :(得分:1)
SELECT
XMLColumnName.value('(/root/item/Name)[1]','varchar(max)') AS firstname,
XMLColumnName.value('(/root/item/Value)[1]','varchar(max)') AS myValue
FROM MyTable
不确定为什么你正在使用'<root>
'标签(通常只有一个用于整个XML值的结束标记)。可能没什么区别,但你必须看到。
答案 1 :(得分:1)
使用动态数量的列,您需要动态SQL。
首先使用您感兴趣的名称/值列表填充临时表。然后从临时表创建动态SQL语句并执行动态查询。
select ID,
X.N.value('(Name/text())[1]', 'varchar(max)') as Name,
X.N.value('(Value/text())[1]', 'varchar(max)') as Value
into #T
from T
cross apply T.XMLCol.nodes('root/item') as X(N)
declare @SQL nvarchar(max)
declare @Col nvarchar(max)
select @Col =
(
select distinct ','+quotename(Name)
from #T
for xml path(''), type
).value('substring(text()[1], 2)', 'nvarchar(max)')
set @SQL = 'select ID,'+@Col+'
from #T
pivot (max(Value) for Name in ('+@Col+')) as P'
exec (@SQL)
drop table #T