web-dev-qa-db-ja.com

SQL Serverは複数の列のピボットを解除します

3つの列(ピボット、列名、値)を取得するために、多くの列を中心にテーブルをピボットしようとしています。

例えば:

name  |  age  |  gender
------+-------+---------
John  |   20  |    M
Jill  |   21  |    F

になるだろう:

name | column | value
-----+--------+-------
John |  age   |   20
John | gender |   M
Jill |  age   |   21
Jill | gender |   F

私はかなりグーグルで検索しましたが、特にピボットが私が達成しようとしているのと反対方向に行われているように見えるため、同様の状況は見つかりませんでした。

10
mathematician

列から行への変換はUNPIVOTと呼ばれます。使用しているSQL Serverのバージョンを指定しませんでしたが、結果を取得する方法はいくつかあります。

UNION ALLSELECTを使用できます:

SELECT name, 'age' as column, cast(age as varchar(10)) as value
FROM yourtable
UNION ALL
SELECT name, 'gender' as column, gender as value
FROM yourtable;

SQL Server 2005+を使用している場合、UNPIVOT関数を使用できます。

SELECT name, column, age
FROM
(
  SELECT 
    name, 
    age = cast(age as varchar(10)), 
    gender
  FROM yourtable
) d
UNPIVOT
(
  value
  for column in (age, gender)
) unpiv;

最後に、UNPIVOT関数の代わりに、CROSS APPLYVALUES(2008+)またはUNION ALLとともに使用することもできます。

SELECT name, column, age
FROM yourtable
CROSS APPLY
(
  VALUES
    ('age', cast(age as varchar(10)),
    ('gender', gender)
) c (column, value);

これらのバージョンのいずれでも、必要な結果が得られます。 age列をvarcharにキャストしなければならなかったことに注意してください。これは、最終結果で列を単一の列に変換するため、列のデータ型/長さ(ピボットなし)が同じでなければならないためです。

21
Taryn
SELECT name, column, value
FROM (SELECT name, age, gender
FROM table) src
UNPIVOT (value FOR column IN (age, gender)) pvt
0
L Vermeulen