2012-02-14 7 views
0
-- Pivot table with one row and four columns 

SELECT 'Values' tValues, 
    ID,Name,ValueID,Value FROM (

     Select ID,Name,ValueID,Value FROM Table WHERE OptionID = 1000000 

    ) AS SourceTable 

    PIVOT ( 

     COUNT(tValues) 
     FOR tValues IN (ID,Attribute,ValueID,Value) 

    ) AS PivotTable; 

することは、私はMicrosoft.comの例をオフに行きますよCOUNT(tValues)のような上記のコードでそれを見ると驚いていますが、これは何のためのものなのか分かりません。マイクロソフトの例から判断すると、それはいつも何らかの数値のように思えます。それが何かを返すかどうかを調べるが、それが返すのはエラーだ。とにかく、なぜ誰かがこのクエリがうまくいかない理由を共有でき、おそらくFORの上にある数値が何のために使われているのかを説明できますか?それは次のようになりますので、ピボットテーブルは

Tableは、4つの列で、行のx量をcontaints:

ID | Name | ValueID | Value 

100 | Color | 10000 | Black 
101 | Size | 10005 | Large 

出力は次のようにする必要があります:あなたはピボットを使用したい場合は

Name_100 | Color | Name_101 | Size | 

10000  | Black | 10005  | Large | 
+0

テーブル、サンプルデータ、および希望の結果を表示できますか? 「うまくいかない」とはどういう意味ですか? –

+0

@Aaron: 'Table'は4列のX個の行結果のリストです。クエリ全体が機能しません。ピボットもこれを処理できますか? –

+1

私は分かりません。だから私はあなたが達成しようとしていることの詳細を尋ねました。テーブル構造( 'CREATE TABLE')、サンプルデータ、そしてクエリの出力をどのように見せたいでしょうか?それ以外の場合は、ピボットが処理すると予想される「これ」が何であるかわかりません。 –

答えて

1

このようなものが多分あります。

これは、名前列が一意のである場合にのみ機能します。そうでない場合は、IDを追加することができます。

だから、最初のいくつかのテストデータ:

CREATE TABLE tblValues 
    (
     ID INT, 
     Name VARCHAR(100), 
     ValueID INT, 
     Value VARCHAR(100) 
    ) 

INSERT INTO tblValues 
VALUES 
    (100,'Color',10000,'Black'), 
    (101,'Size',10005,'Large') 

次にあなたが旋回するように列を取得する必要があります:

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     ''Name_''+CAST(tbl.ID AS VARCHAR(100)) AS pivotName, 
     CAST(tbl.ValueID AS VARCHAR(100)) AS name 
    FROM 
     tblValues AS tbl 
    UNION ALL 
    SELECT 
     tbl.Name AS pivotName, 
     tbl.Value AS name 
    FROM 
     tblValues AS tbl 
) AS p 
PIVOT 
(
    MAX(name) 
    FOR pivotName IN ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

DECLARE @cols VARCHAR(MAX) 
;WITH CTE AS 
(
    SELECT 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Name, 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     tblValues AS tbl 
    UNION ALL 
    SELECT 
     tbl.Name, 
     'Value_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     tblValues AS tbl 
) 
SELECT 
    @cols = COALESCE(@cols + ','+QUOTENAME(Name), 
       QUOTENAME(Name)) 
FROM 
    CTE 
ORDER BY 
    CTE.ID, 
    CTE.Sort 

次に、このような動的SQLを宣言し、実行します

私の場合、私が作成したテーブルを落とす

DROP TABLE tblValues 

編集

それとも、それはこのようなものでなければなりません場合は:

まず列:次に

DECLARE @cols VARCHAR(MAX) 
;WITH CTE AS 
(
    SELECT 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Name, 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
    UNION ALL 
    SELECT 
     tbl.Name, 
     'Value_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
) 
SELECT 
    @cols = COALESCE(@cols + ','+QUOTENAME(Name), 
       QUOTENAME(Name)) 
FROM 
    CTE 
ORDER BY 
    CTE.ID, 
    CTE.Sort 

動的SQL。

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     ''Name_''+CAST(tbl.ID AS VARCHAR(100)) AS pivotName, 
     CAST(tbl.ValueID AS VARCHAR(100)) AS name 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
    UNION ALL 
    SELECT 
     tbl.Name AS pivotName, 
     tbl.Value AS name 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
) AS p 
PIVOT 
(
    MAX(name) 
    FOR pivotName IN ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

テーブルを作成するか、テーブルを削除する必要はありません。それは、私のデータベースにあなたのテーブルがなく、他の誰かがその例を実行したいと思っているからです。

+0

元のテーブルにすでにこれらの値が入っている場合は、テーブル 'tblValues'を作成する必要がありますか? (質問の 'SELECT'文に示されているように) –

+0

私は答えを更新しました。あなたがその答えを知っているなら、それを受け入れることを検討するかもしれません。 – Arion

1

列数が可変のテーブルを作成する場合は、次の行に沿って何かを使用することをお勧めします。

DECLARE @cols VARCHAR(4000) 
    DECLARE @query VARCHAR(8000) 
    SELECT @cols = STUFF((SELECT DISTINCT 
      '],[' + Name 
         FROM Table 
         ORDER BY '],[' + Name 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 

    SET @query = 
    'SELECT * FROM 
    (
     SELECT col1, col2, col3, whateverColYourInterestedIn, Name, Value 
     FROM Table 
    )t 
    PIVOT (MAX(Value) FOR Name 
    IN ('[email protected]+')) AS pvt' 

    EXECUTE (@query) 

これはおそらく正しくはありませんが、それはうまくいけばあなたの出発点になるはずです。詳細情報については

、このようthisthisなどのリンクをチェックしてください。

+0

これは私が示唆したことですが、あなたのクエリは少しきれいにする必要があります。 SELECT DISTINCTに一重引用符がありません。サブクエリでORDER BYを実行することは、NO-NO-SQL Serverが実際にそれについて気をつけなければなりません。 :) – FarligOpptreden

+0

ノートをありがとう。不足している見積もりを追加しました。サブ問合せにはORDER BYはありません。STUFFに渡すパラメータで使用されます。動的列リストを構築するために私が見たすべての例が、どのようにして私がそれを成功裏に使用したかです。私は、コードがうまくいかないかもしれないことに同意しますが、うまくいけばOPにいくつかのアイデアが与えられ、関連するリンクは残りの部分をまとめてクエリを働かせるのに役立ちます。 –

+0

私は実際にSTUFFに渡すクエリのORDER BYを参照していました。私はその数回についてSQL Serverの憂鬱を抱えていました。そして、ROW_NUMBER()OVER(ORDER BY ...)ハックを使ってSELECTをCTEに入れてデータを取得し、 STUFF内のCTEから関連する列。私はそれが最もダイナミックな実装だと信じて答えをアップアップしました。あなたはsp_ExecuteSQLを呼び出して、クエリパスがキャッシュされていることを確認することもできます。 – FarligOpptreden