0

テーブルを値のカウントを含むXMLに変換する必要があります。

例えば

Table
Id , Type, AnotherType
1, This, Widget
2, This, Fimble
3, That, Widget

このような出力が必要です。これは動的である必要があるため、新しい列またはファセットを追加すると、このタイプの出力が生成されます。

<matrix name="Type">
 <facet name = "this" count=2>
   <id value = 1></id>
   <id value = 2></id>
 </facet>     
 <facet name = "that" count=1>
   <id value = 3></id>
 </facet>
</matrix>
<matrix name="AnotherType">
 <facet name = "Widget" count=2>
   <id value = 1></id>
   <id value = 3></id>
 </facet>
 <facet name = "Fimble" count=1>
   <id value = 2></id>
 </facet>
</matrix>

これは可能ですか?

列/値が変更された場合、それを処理するソリューションが必要です。たとえば、データに応じて新しいマトリックスとファクトが生成されます。

4

3 に答える 3

2

UNPIVOTこれは可能ですが、コマンドと動的 SQLを適用する必要があります。これをいくつかの段階に分けた方が良いです:

1)テーブルにはさまざまな列を含めることができます。最初にすべきことは、列のリストを取得することです。すべての列がsys.columns表にリストされています。次のコードは、列のリストを取得し、カンマ区切りのリストとして保存します。ただし、最初の列は別々に保存されます(さらなる目的のため)。

DECLARE @firstColumn NVARCHAR(256)
DECLARE @columnList NVARCHAR(MAX)

SELECT @firstColumn = name 
    FROM sys.columns 
    WHERE object_id = OBJECT_ID(@tableName) 
        AND column_id = 1
SET @columnList = N''

SELECT @columnList = @columnList + name + N',' 
    FROM sys.columns 
    WHERE object_id = OBJECT_ID(@tableName) 
        AND column_id > 1

SET @columnList = LEFT(@columnList,LEN(@columnList)-1)

2)構造をより「プログラマーフレンドリー」にするためにUNPIVOTドキュメントはこちら)コマンドを使用したい。そのためには列のリストが必要です。動的 SQL を使用して実行できます (例はこちら)。次のコマンドは、ジョブを実行します。

DECLARE @cmd NVARCHAR(MAX)

SET @cmd = N'INSERT INTO #unPivoted
    SELECT id, Matrixes, Facets 
    FROM 
        (SELECT ' + @firstColumn + N',' + @columnList + N' FROM ' + @tableName + N') p
    UNPIVOT
        (Facets FOR Matrixes IN(' + @columnList + N')) AS unpvt
    ORDER BY Matrixes,Facets,id'

EXEC sp_executesql @cmd

あなたの例では、次のような結果が生成されます。

id | Matrixes    | Facets
-------------------------
2  | AnotherType | Fimble
1  | AnotherType | Widget
3  | AnotherType | Widget
3  | Type        | That
1  | Type        | This
2  | Type        | This

3)最後は実際のクエリです。FOR XML AUTOコマンドを使用するだけで十分です。ただし、ネストされたクエリを作成して、構造を希望どおりに見せる必要があります。

SELECT matrix.name, facet.name, facet.id_count AS count, id.id AS value 
FROM 
    (SELECT DISTINCT Matrixes AS name FROM #unPivoted) matrix
INNER JOIN 
    (SELECT Matrixes AS matrix_name, Facets AS name, COUNT(id) AS id_count FROM #unPivoted GROUP BY Matrixes, Facets) facet 
    ON matrix.name = facet.matrix_name 
INNER JOIN 
    (SELECT Facets AS facet_name, id FROM #unPivoted) id 
    ON facet.name = id.facet_name
ORDER BY matrix.name, facet.name, id.id
FOR XML AUTO

そしてストアドプロシージャ。すべての PRINT と SELECT を残して、それがどのように機能するかを確認してください (説明が不十分な場合)。

CREATE PROCEDURE usp_tableToXML
    @tableName NVARCHAR(256)
AS
BEGIN

SET NOCOUNT ON;

-- 1. Get columns from the table
DECLARE @firstColumn NVARCHAR(256)
DECLARE @columnList NVARCHAR(MAX)

SELECT @firstColumn = name 
FROM sys.columns 
WHERE object_id = OBJECT_ID(@tableName) 
AND column_id = 1

SET @columnList = N''

SELECT @columnList = @columnList + name + N',' 
FROM sys.columns 
WHERE object_id = OBJECT_ID(@tableName) 
AND column_id > 1

SET @columnList = LEFT(@columnList,LEN(@columnList)-1)

PRINT @firstColumn
PRINT @columnList

-- 2. Unpivot the table
CREATE TABLE #unPivoted
(
    id INT,
    Matrixes VARCHAR(30),
    Facets VARCHAR(30)
)

DECLARE @cmd NVARCHAR(MAX)

SET @cmd = N'INSERT INTO #unPivoted
SELECT id, Matrixes, Facets 
FROM 
    (SELECT ' + @firstColumn + N',' + @columnList + N' FROM ' + @tableName + N') p
UNPIVOT
    (Facets FOR Matrixes IN(' + @columnList + N')) AS unpvt
ORDER BY Matrixes,Facets,id'

PRINT @cmd

EXEC sp_executesql @cmd

SELECT * FROM #unPivoted

-- 3. The query
SELECT matrix.name, facet.name, facet.id_count AS count, id.id AS value 
FROM 
    (SELECT DISTINCT Matrixes AS name FROM #unPivoted) matrix
INNER JOIN 
    (SELECT Matrixes AS matrix_name, Facets AS name, COUNT(id) AS id_count FROM #unPivoted GROUP BY Matrixes, Facets) facet 
    ON matrix.name = facet.matrix_name 
INNER JOIN 
    (SELECT Facets AS facet_name, id FROM #unPivoted) id 
    ON facet.name = id.facet_name
ORDER BY matrix.name, facet.name, id.id
FOR XML AUTO

END
GO

EXEC usp_tableToXML 'Types'

ところで、XML 構造に少し誤りがあったと思います。次のようにすべきではありませんか ( facetID の後にタグを閉じる必要がありますか?):

<matrix name="AnotherType">
  <facet name="Fimble" count="1">
    <id value="2" />
  </facet>
  <facet name="Widget" count="2">
    <id value="1" />
    <id value="3" />
  </facet>
</matrix>
<matrix name="Type">
  <facet name="That" count="1">
    <id value="3" />
  </facet>
  <facet name="This" count="2">
    <id value="1" />
    <id value="2" />
  </facet>
</matrix>
于 2009-12-11T12:32:18.070 に答える
0

SQL Server 2005以降を使用している場合は、次のようにすることができます

于 2009-12-08T08:35:01.987 に答える
0

こちらをご覧ください: CTE and Hierarchical XML Result . XSLT 部分を無視して、XML のみに固執することができます。

編集:もう少しトリックのようです。こちらをご覧ください:純粋な TSQL CTE 命令を使用して階層型 XML を生成するため、ツリービューにデータを入力するための SQL XML 出力。

于 2009-12-08T08:46:25.457 に答える