我有一个包含列的表[users]:
[id] int
[userdetails] nvarchar(max)
[userdetails]包含以下数据:
<Attributes>
<Map>
<entry key="displayName" value="Administrator"/>
<entry key="email" value="joe.blow@google.com"/>
<entry key="firstname" value="Joe"/>
<entry key="lastname" value="tdehdgthrth"/>
<entry key="another1" value="rthrth"/>
<entry key="another7" value="etdsryhntdhetdyh"/>
<entry key="anotherWhatever" value="6546544"/>
</Map>
</Attributes>
每行可以包含键/值元素计数的不同组合。
在查询中,我想提取所有不同(跨所有行)KEY值的列表。这甚至可能吗?
我之前曾问过类似的问题:
https://stackoverflow.com/a/50281264/8678
从上面查询特定元素的语法如下:
declare @tbl table(id int, userdetails nvarchar(max))
insert @tbl(id,userdetails)
values(1,'<Attributes>
<Map>
<entry key="displayName" value="Administrator"/>
<entry key="email" value="joe.blow@google.com"/>
<entry key="firstname" value="Joe"/>
<entry key="lastname" value="Blow"/>
</Map>
</Attributes>')
;with tbl as (
select id,cast(userdetails as xml) ud
from @tbl)
select id,
t.v.value('entry[@key="displayName"][1]/@value','nvarchar(100)') displayName,
t.v.value('entry[@key="email"][1]/@value','nvarchar(100)') email,
t.v.value('entry[@key="firstname"][1]/@value','nvarchar(100)') firstname,
t.v.value('entry[@key="lastname"][1]/@value','nvarchar(100)') lastname
from tbl
cross apply ud.nodes('Attributes/Map') t(v)
这个问题的一个明显问题是,它需要知道可用的值并在SQL中对它们进行硬编码,而我在这里要做的是发现可能的键值的不同集合
答案 0 :(得分:2)
在查询中,我想提取所有不同(跨所有行)KEY值的列表。这甚至可能吗?
我在这里要做的是发现不同的可能键值是什么。
这将生成所有行中不同键的列表(注意:我不确定每个键值可能有多长,但这只会抓取100个字符;必要时更改):
;WITH tbl AS (
SELECT id, cast(userdetails as xml) ud
FROM testSo)
SELECT DISTINCT
t.v.value('(@key)[1]','nvarchar(100)') anEntryKey
FROM tbl
CROSS APPLY ud.nodes('//entry') t(v)
如果您需要获取有关每个来自哪个地方的更多信息(哪个ID),您可以获得这样的(非不同的)列表:
;WITH tbl AS (
SELECT id, cast(userdetails as xml) ud
FROM testSo)
SELECT
id,
t.v.value('(@key)[1]','nvarchar(100)') anEntryKey
FROM tbl
CROSS APPLY ud.nodes('//entry') t(v)
我使用SQL Server 2017在SQL Fiddle here上测试了这些。