我在MS SQL Server数据库中有一个表,其结构如下:
| goodId | pos | description | docType | isKey |
+--------+---------+-------------+----------------+-------+
| 1417 | NULL | List 1050 | 1050.0000.0000 | 0 |
| 1417 | 2.1.1.1 | hgfhgf9 | 1050.0002.0000 | 1 |
| 1417 | 2.1.1.2 | hghgfh0 | 1050.0002.0000 | 1 |
| 1417 | 2.1.1.3 | wwwwww | 1050.0002.0000 | 1 |
| 1417 | NULL | List 1030 | 1030.0000.0000 | 0 |
| 1417 | 1.3.7.6 | tdgfdgfd | 1030.0001.0001 | 1 |
| 1417 | 9.2.1.2 | gdfgfdfd | 1030.0001.0009 | 1 |
| 1417 | 9.2.1 | dddddddd | 1030.0002.0009 | 1 |
在最后一列[docType]中,前4个字符表示列表编号,后4个字符表示部件编号。我需要获取isKey = 1的位置,但是列表的描述应该从只填充4个第一个字符的行中获取(这将是该列表的描述)
我希望使用SQL XML从此表中获取XML结构:
<good Id="1417">
<list num="1050" description="List 1050">
<part num="2">
<pos num = "2.1.1.1"/>
<pos num= "2.1.1.2"/>
<pos num= "2.1.1.3"/>
</part>
</list>
<list num="1030" description="List 1030">
<part num="1">
<pos num = "1.3.7.6"/>
<pos num = "9.2.1.2"/>
</part>
<part num="2">
<pos num = "9.2.1"/>
</part>
</list>
</good>
我应该编写什么查询来获取此XML结构?
答案 0 :(得分:1)
不记得是否可以不使用这样的重型嵌套:
;with cte as (
select
goodId, pos, description,
left(docType, 4) as list_num,
cast(substring(docType, 6, 4) as int) as part_num,
left(docType, 9) as full_part_num
from Table1
)
select
t1.goodId as Id,
(
select
t2.list_num as num,
t2.description,
(
select
t3.part_num as num,
(
select
t4.pos as num
from cte as t4
where t4.full_part_num = t3.full_part_num
for xml raw('pos'), type
)
from cte as t3
where
t3.goodId = t1.goodId and t3.list_num = t2.list_num and
t3.pos is not null
group by t3.part_num, t3.full_part_num
for xml raw('part'), type
)
from cte as t2
where t2.goodId = t1.goodId and t2.pos is null
for xml raw('list'), type
)
from cte as t1
group by t1.goodId
for xml raw('good');
<强> sql fiddle demo 强>
答案 1 :(得分:1)
怪异的查询。
declare @MyTable table (goodId int, pos varchar(100), description varchar(100), docType varchar(100), isKey bit)
insert into @MyTable (goodId, pos, description, docType, isKey) values
(1417, NULL, 'List 1050', '1050.0000.0000', 0),
(1417, '2.1.1.1', 'hgfhgf9', '1050.0002.0000', 1),
(1417, '2.1.1.2', 'hghgfh0', '1050.0002.0000', 1),
(1417, '2.1.1.3', 'wwwwww', '1050.0002.0000', 1),
(1417, NULL, 'List 1030', '1030.0000.0000', 0),
(1417, '1.3.7.6', 'tdgfdgfd', '1030.0001.0001', 1),
(1417, '9.2.1.2', 'gdfgfdfd', '1030.0001.0009', 1),
(1417, '9.2.1', 'dddddddd', '1030.0002.0009', 1)
select g.goodId as '@Id'
, (
select l.num as '@num'
, l.description as '@description'
, (
select cast(pa.num as int) as '@num'
, (
select po.pos as '@num'
from @MyTable po
where g.goodId = po.goodId and po.pos is not null and l.num = parsename(po.docType, 3) and pa.num = parsename(po.docType, 2)
for xml path('pos'), type
) as [*]
from (
select distinct parsename(pa.docType, 2) num
from @MyTable pa
where g.goodId = pa.goodId and pa.pos is not null and l.num = parsename(pa.docType, 3)
) pa
for xml path('part'), type
) as [*]
from (
select distinct parsename(l.docType, 3) num, l.description
from @MyTable l
where g.goodId = l.goodId and l.pos is null
) l
order by l.num
for xml path('list'), type
) as [*]
from (
select distinct goodId
from @MyTable
) g
for xml path('good'), type