2012-03-29 15 views
0

SQLのシナリオに関する別の愚かな質問です。テーブル構造でSQLクエリ - ほぼピボットテーブルのような?

FieldKey DocumentKey FieldId FieldValue 
1 00001c55-aab3-4df8-a07e-8eac162fa075 TITLE Mass Import 18355 
2 00001c55-aab3-4df8-a07e-8eac162fa075 1 00001c55-aab3-4df8-a07e-8eac162fa075 
3 00001c55-aab3-4df8-a07e-8eac162fa075 2 9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89 
4 00001c55-aab3-4df8-a07e-8eac162fa075 3 18355 
5 00001c55-aab3-4df8-a07e-8eac162fa075 4 94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6 
6 00001c55-aab3-4df8-a07e-8eac162fa075 5 Created by C# mass import 
7 00002205-00D3-4495-B65A-A7B1FD2AE7F2 TITLE Mass Import 1494780 
8 00002205-00D3-4495-B65A-A7B1FD2AE7F2 1 00002205-00D3-4495-B65A-A7B1FD2AE7F2 
9 00002205-00D3-4495-B65A-A7B1FD2AE7F2 2 870386312 
10 00002205-00D3-4495-B65A-A7B1FD2AE7F2 3 1494780 
11 00002205-00D3-4495-B65A-A7B1FD2AE7F2 4 -1929051324 
13 00002342-6de0-4110-b576-fd32f96b2858 TITLE Mass Import 387008 
14 00002342-6de0-4110-b576-fd32f96b2858 1 00002342-6de0-4110-b576-fd32f96b2858 
15 00002342-6de0-4110-b576-fd32f96b2858 2 B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51 
16 00002342-6de0-4110-b576-fd32f96b2858 3 387008 

:次のような

考えるデータ

[FieldKey] [bigint] IDENTITY(1,1) NOT NULL, 
[DocumentKey] [char](36) NOT NULL, 
[FieldId] [varchar](10) NOT NULL, 
[FieldValue] [varchar](255) NOT NULL 

水平にこのデータを反転するための最良の方法は何ですか?理想的には:

DocumentKey        TITLE 1 2 3 4 5 
00001c55-aab3-4df8-a07e-8eac162fa075 mytitle val1 val2 val3 val4 val5 
00002205-00D3-4495-B65A-A7B1FD2AE7F2 mytitle2 val6 val7 val8 val9 
00002342-6de0-4110-b576-fd32f96b2858 mytitle3 vl10 vl11 vl12 

私は、ピボットテーブルがうまくいくかもしれないと思ったし、それは近いですが、問題は、私はSQLピボットために必要な集約を必要としないです。私はちょうどデータを反転したい。列数(私の例では1-5プラスTITLE)はTITLEと1-30の間の任意の値になります。

多分私は高密度であるかもしれませんが、どんなアイデアも高く評価されます。

答えて

2

私はあなたがPIVOTと正しい軌道に乗っていると思います。あなたは、値の列に集計を持っているつもりです。しかし、あなたが言うように、1〜30列とタイトル列を持つことになります。

テストデータ

CREATE TABLE Table1 
(
    [FieldKey] [bigint] NOT NULL, 
    [DocumentKey] [char](36) NOT NULL, 
    [FieldId] [varchar](10) NOT NULL, 
    [FieldValue] [varchar](255) NOT NULL 
) 
INSERT INTO Table1 
VALUES 
    (1,'00001c55-aab3-4df8-a07e-8eac162fa075','TITLE','Mass Import 18355'), 
    (2,'00001c55-aab3-4df8-a07e-8eac162fa075','1','00001c55-aab3-4df8-a07e-8eac162fa075'), 
    (3,'00001c55-aab3-4df8-a07e-8eac162fa075','2','9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89'), 
    (4,'00001c55-aab3-4df8-a07e-8eac162fa075','3','18355'), 
    (5,'00001c55-aab3-4df8-a07e-8eac162fa075','4','94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6'), 
    (6,'00001c55-aab3-4df8-a07e-8eac162fa075','5','Created by C# mass import'), 
    (7,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','TITLE','Mass Import 1494780'), 
    (8,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','1','00002205-00D3-4495-B65A-A7B1FD2AE7F2'), 
    (9,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','2','870386312'), 
    (10,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','3','1494780'), 
    (11,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','4','-1929051324'), 
    (13,'00002342-6de0-4110-b576-fd32f96b2858','TITLE','Mass Import 387008'), 
    (14,'00002342-6de0-4110-b576-fd32f96b2858','1','00002342-6de0-4110-b576-fd32f96b2858'), 
    (15,'00002342-6de0-4110-b576-fd32f96b2858','2','B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51'), 
    (16,'00002342-6de0-4110-b576-fd32f96b2858','3','387008') 

検索独特の列

DECLARE @cols VARCHAR(MAX) 
;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY Table1.FieldId 
           ORDER BY Table1.FieldId) AS RowNbr, 
     Table1.* 
    FROM 
     Table1 
) 
SELECT @cols=STUFF 
(
    (
     SELECT 
      ',' +QUOTENAME(CTE.FieldId) 
     FROM 
      CTE 
     WHERE 
      CTE.RowNbr=1 
     ORDER BY 
      LEN(CTE.FieldId) DESC, 
      CTE.FieldId 
     FOR XML PATH('') 
    ) 
,1,1,'') 
:それは、提案は(それが唯一のSQL Serverのである2005+)です。ここダイナミックピボット

が必要です

TITLEが最初に来るように注文する必要があります。 FOR XML PATHは列を連結します。

ダイナミックピボット

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     Table1.DocumentKey, 
     Table1.FieldId, 
     Table1.FieldValue 
    FROM 
     Table1 
) AS p 
PIVOT 
(
    MAX(FieldValue) 
    FOR FieldId IN('[email protected]+') 
) AS p' 
EXECUTE(@query) 

私はOPが静的ピボットを望んでいたとは思わない(必須ではありません)自分の後に

DROP TABLE Table1 
2

SQL Server 2005以降を使用している場合は、PIVOT演算子を使用できます。

select [DocumentKey], [TITLE], [1], [2], [3], [4], [5] 
from (select [DocumentKey], FieldId, FieldValue from TableName) t 
    pivot (max(FieldValue) for FieldID in ([TITLE], [1], [2], [3], [4], [5])) as pvt 
order by [DocumentKey] 

あなたは追加の列を追加する必要があります、6 - 30

+1

をクリーンアップします。列が1-30の間で変化するかどうかは考慮されません。 – Arion

+1

確かに、30列すべてを追加します。列が存在しない場合は、値がnullになります。問題の要点は「問題は、SQLピボットに必要な集約が必要ないことです。データを反転したいだけです。」 MAX関数を使用してください。 – jim31415

+0

どちらもtrue :)最終的にダイナミックなので、短期的には不要ですが、30以上の列を持つことがあります。 – Kettch19

関連する問題