이 작업을 수행 할 수 있지만 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
(documentation here) 명령을 사용합니다. 우리는 그것을하기 위해 기둥 목록이 필요합니다. 동적 SQL (example here)을 사용하여 수행 할 수 있습니다. 이 같은 결과를 생성합니다 귀하의 예에서
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
명령을 사용하면됩니다. 그러나 구조를 원하는 모양으로 만들기 위해 중첩 된 쿼리를 만들어야합니다.
그리고 저장 프로 시저. 나는 당신이 모든 인쇄물과 선택을 남겨 두어 설명이 충분하지 않다면 어떻게 작동하는지 보았다.
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'
Btw, 나는 XML 구조를 약간 잘못했다고 생각합니다. 그것은 (? facet
태그 식별자 후 닫아야)이처럼 안 :
<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>
놀라운, 매력처럼 작동하는 것 같습니다. – Coolcoder
필자는 이것을 받아 들였지만 이상적으로는 테이블이 아닌 훌륭한 작업으로 쿼리를 처리해야합니다. 정말 좋은 물건. – Coolcoder
나는이 코드를 사용하여 proc 내에서 코드가 사용되도록했다. 다시 환상적입니다. – Coolcoder