2017-05-12 16 views
-1

問題があります。同じテーブルに参加してその列を作成しようとしています。例えば、表はid,name,typeを含む。SQL外部ピボットテーブルを使用して同じテーブルに結合する

とデータが使用できます

id   name   type   Date 
-------------------------------------------------- 
1   KKKK   BP   05/05/2017 
2   MMMM   KS   07/10/2016 
3   LLL    TL   04/05/2017 
4   NNN    BP   06/01/2016 

私は次のような設計でテーブルを作りたい:

- id name  BP     KS     TL 
------------------------------------------------------------- 
1  KKK 05/05/2017 
2  MMM      07/10/2016 
3  LLL           04/05/2017 
4  NNN 06/01/2017 

私はピボットテーブルを試してみましたが、うまくいきませんでした。

+1

この問題を解決するには、TSQLの試みをお見せください。ありがとう! –

+0

ピボットの問題は、26種類の異なるタイプにすることができ、1つの名前は同じクラスと異なる日付を持つことができるため、その場合は別の列を追加したいと考えています。 – Luis64

答えて

2

あなたは、列へのデータのあなたの行を変換するために、SQL Server 2008でPIVOT機能を使用することができます。

select 
    id, 
    name, 
    BP, KS, TL 
from 
(
    select id, 
    name, 
    type, 
    [date] 
    from mytable 
) d 
pivot 
(
    max([date]) 
    for type in (BP, KS, TL) 
) piv; 

これはまた、いくつかの集約とCASE表現のように、条件付きロジックを使用して記述できます。

select id, 
    name, 
    BP = max(case when type = 'BP' then [date] end), 
    KS = max(case when type = 'KS' then [date] end), 
    TL = max(case when type = 'TL' then [date] end) 
from mytable 
group by id, name; 

nametypeの組み合わせで複数の日付を設定できるというご意見に基づいて、同様のクエリを使用することができます.wi row_numberのような機能を使って、あなたが望む最終結果を得ることができます。

あなたが条件ロジックのバージョンを使用したい場合は、あなたがするクエリを変更したい:

select 
    name, 
    BP1 = max(case when type = 'BP' and rn =1 then [date] end), 
    BP2 = max(case when type = 'BP' and rn =2 then [date] end), 
    BP3 = max(case when type = 'BP' and rn =3 then [date] end), 
    KS1 = max(case when type = 'KS' and rn =1 then [date] end), 
    KS2 = max(case when type = 'KS' and rn =2 then [date] end), 
    TL1 = max(case when type = 'TL' and rn =1 then [date] end) 
from 
(
    select 
    name, 
    [type], 
    [date], 
    rn = row_number() over(partition by name, [type] order by [date] desc) 
    from mytable 
) d 
group by name; 

PIVOTのバージョンは次のようになります。

select 
    name, 
    BP1, BP2, BP3, KS1, KS2, TL1 
from 
(
    select 
    name, 
    type = type + cast(rn as varchar(2)), 
    [date] 
    from 
    (
    select 
     name, 
     type, 
     [date], 
     rn = row_number() over(partition by name, [type] order by [date] desc) 
    from mytable 
)s 
) d 
pivot 
(
    max([date]) 
    for type in (BP1, BP2, BP3, KS1, KS2, TL1) 
) piv; 

あなたがそこにある見ることができるようにこれらの列をすべて取得するために多くのタイプを入力するので、動的SQLを使用して最終的な結果を得ることができます。

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

select @cols = STUFF((SELECT ',' + QUOTENAME(Type + cast(rn as varchar(2))) 
        from 
        (
         select type, 
         rn = row_number() over(partition by name, type order by date desc) 
         from mytable 
        ) d 
        group by type, rn 
        order by type, rn 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = N'SELECT name, ' + @cols + N' 
      from 
      (
       select 
        name, 
        type = type + cast(rn as varchar(2)), 
        [date] 
       from 
       (
        select 
        name, 
        type, 
        [date], 
        rn = row_number() over(partition by name, [type] order by [date] desc) 
        from mytable 
       )s 
      ) x 
      pivot 
      (
       max(date) 
       for type in (' + @cols + N') 
      ) p ' 

exec sp_executesql @query; 

demoを作成して、すべて同じ結果を返すことを示します。

+0

タイプはテーブルであり、そのタイプは25種類あります。同じ名前は同じタイプと異なる日付を持つことがありますので、別のカラムを作成したいこともあります。 – Luis64

+0

@ Luis64「同じ名前の同じ名前と同じ日付が何度か」というのはどういう意味ですか?これらの詳細をオリジナルの質問に含める必要があります。これを示すサンプルデータと最終的な希望結果で質問を編集してください。 – ollie

+0

同じ名前、同じクラス、異なる日なので、余計な列を作成したい – Luis64