2

私は次のデータを持っています

代替テキスト

(SQL Server 2005 で) 次の形式に変換するにはどうすればよいですか?

代替テキスト

私が思いついた解決策の例がありますが、少しぎこちないようです。もしかして臭い?

DECLARE @ProductLanguage TABLE
(
    [PRODUCT_ID] int
    , [LANGUAGE] varchar(50)
)

INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'Czech')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'English')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'German')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'Danish')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'Spanish')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'English')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Finnish')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Greek')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Hungarian')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52044,'Hebrew')

SELECT
    PRODUCT_ID
    ,MAX(CASE WHEN [ROW_ID]=1 THEN LANGUAGE ELSE NULL END) As LANG_1
    ,MAX(CASE WHEN [ROW_ID]=2 THEN LANGUAGE ELSE NULL END) As LANG_2
    ,MAX(CASE WHEN [ROW_ID]=3 THEN LANGUAGE ELSE NULL END) As LANG_3
FROM
    (SELECT
        ROW_NUMBER() OVER (PARTITION BY [PRODUCT_ID] ORDER BY [PRODUCT_ID] ASC) AS [ROW_ID]
        , [PRODUCT_ID]
        , [LANGUAGE]
    FROM
        @ProductLanguage) AS Temp
GROUP BY
    [PRODUCT_ID]

興味深いことに、各 LANG_* 列に表示される特定の言語は気にしません。ここに投稿された他の質問はすべて、ピボットされた列を名前で知ることに言及しているようです。しかし、見つかった言語で列に名前を付けたくありません。

:「ピボット」という言葉に言及していることは知っていますが、この問題の最善の解決策には PIVOT 句が含まれない場合があります。私の質問がデータのピボットを示唆しているように見えたので、私はその言葉を使用しました。おそらくCTEが解決に役立つでしょうが、私にはわかりません。上記のソリューション例に満足していないことはわかっています。

4

4 に答える 4

3

PIVOT() 関数を使用できます

SELECT    P.PRODUCT_ID,
          P.Czech,
          P.Other languages
FROM      TABLE AS T
PIVOT     (
              AGGREGATE(LANGUAGE) FOR LANGUAGE IN ([Czech],  ...)
          ) AS P

列に明示的に名前を付けないと、私の知る限り、トリックを行う必要があります...

テストされていません(明らかに)。参照: MSDN

于 2008-12-19T03:06:50.823 に答える
1

これはPIVOT、静的または動的に で実行できます。

静的バージョンの列はハードコードされています ( SQL Fiddle with Demoを参照):

select *
from 
(
  select product_id, language,
    'Lang_' + cast(row_number() over(partition by PRODUCT_ID order by language) as varchar(10)) rn
  from ProductLanguage
) x
pivot
(
  max(language)
  for rn in ([Lang_1], [Lang_2], [Lang_3])
) p

動的バージョンは実行時に列を取得します ( SQL Fiddle With Demoを参照)。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Lang_' + cast(row_number() over(partition by PRODUCT_ID order by language) as varchar(10))) 
                    from ProductLanguage
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT PRODUCT_ID, ' + @cols + ' from 
             (
              select product_id, language,
                ''Lang_'' + cast(row_number() over(partition by PRODUCT_ID order by language) as varchar(10)) rn
              from ProductLanguage
            ) x
            pivot 
            (
                max(language)
                for rn in (' + @cols + ')
            ) p '

execute(@query)
于 2012-09-21T03:00:42.420 に答える
0

ここにアイデアがあります... Pivotキーワードを使用してください... sql2005で利用可能

ピボットとアンピボット

次に、この作業を行った後、列名をデータ値として出力し、この SQL ステートメント全体を外側の Select ステートメント内のサブクエリとして埋め込みます。ここで、列名を「Language1」、「Language2」などにエイリアスします...

Select Z.Arabic as Language1, Z.Botwanese as Language2, etc.
From  (Inner Pivot Query Here ) Z
于 2008-12-19T02:52:34.767 に答える