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

巨大なクエリ。

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 に答える
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 に答える