1

我在 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 结构?

4

2 回答 2

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

于 2013-10-09T14:00:18.740 回答
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
于 2013-10-09T14:05:20.767 回答