web-dev-qa-db-ja.com

行を列にフラット化しようとしています

IDを持つテーブルの行のグループがあります。複数の列がある行でそれを平らにしようとしています。私はこれをcteとおそらくパーティションで実行したことはほぼ確実です。

Cteを使用して重複データを削除しましたが、ここで達成しようとしているのと同じようなことをしたと思います。実用的なソリューション(以下に記載)を思いついたのですが、よりエレガントなソリューションを利用できるように思えます。

CREATE TABLE #MyTable ( RowID int , field VARCHAR(10), value  VARCHAR(10))  

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 1, 'first', 'neil' )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 2, 'first', 'bob'  )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 3, 'first', 'tom'  )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 1, 'last', 'young' )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 2, 'last', 'dylan' )

INSERT INTO #MyTable ( RowID, field, value ) VALUES  ( 3, 'last', 'petty' )

SELECT * FROM #mytable

-cte/partitionでこれを達成しようとします。

SELECT rowid, 
   [first] = (Select value FROM #mytable where field = 'first' and rowid = t.rowid), 
   [last] = (Select value FROM #mytable where field = 'last' and rowid = t.rowid)
FROM #mytable t
GROUP BY rowid
20
boone

このデータ変換は PIVOT として知られています。 SQL Server 2005+には、このプロセスを実行する関数があります。 :

select *
from
(
  SELECT * 
  FROM mytable
) src
pivot
(
  max(value)
  for field in (first, last)
) piv

SQL Fiddle with Demo を参照してください。

または、CASE式で集約関数を使用できます。

select rowid,
  max(case when field = 'first' then value end) first,
  max(case when field = 'last' then value end) last
from MyTable
group by rowid

SQL Fiddle with Demo を参照してください。

テーブルで複数の結合を使用することもできます。

select t1.rowid,
  t1.value first,
  t2.value last
from mytable t1
left join mytable t2
  on t1.rowid = t2.rowid
  and t2.field = 'last'
where t1.field = 'first'

参照 SQL Fiddleデモあり

すべてのバージョンの結果は同じです:

| ROWID | FIRST |  LAST |
-------------------------
|     1 |  neil | young |
|     2 |   bob | dylan |
|     3 |   tom | petty |
28
Taryn