同じ種類のデータを含む9つの列を持つデータベースにテーブルがあります。これらの値はnullでも可です。 null以外の各値を、元の行のIDを気にしない値の単一列に選択する必要があります。
したがって、次のような表の場合:
+---------+------+--------+------+
| Id | I1 | I2 | I3 |
+---------+------+--------+------+
| 1 | x1 | x2 | x7 |
| 2 | x3 | null | x8 |
| 3 | null | null | null|
| 4 | x4 | x5 | null|
| 5 | null | x6 | x9 |
+---------+------+--------+------+
Xで始まる各値を単一の列に選択したいと思います。結果のデータは次の表のようになります。順序を保持する必要があるため、最初の行の最初の列の値が一番上にあり、最後の行の最後の列の値が一番下にある必要があります。
+-------+
| value |
+-------+
| x1 |
| x2 |
| x7 |
| x3 |
| x8 |
| x4 |
| x5 |
| x6 |
| x9 |
+-------+
SQL Server 2008 R2を使用しています。これを達成するために、各行から各列の値を順番に選択し、非ヌル値を結果に挿入するよりも良い方法はありますか?
UNPIVOT関数を使用して、最終結果を取得できます。
select value
from yourtable
unpivot
(
value
for col in (I1, I2, I3)
) un
order by id, col;
SQL Server 2008+を使用しているため、CROSS APPLYをVALUES句と共に使用して列のピボットを解除することもできます。
select value
from yourtable
cross apply
(
values
('I1', I1),
('I2', I2),
('I3', I3)
) c(col, value)
where value is not null
order by id, col
SELECT value FROM (
SELECT ID, 1 AS col, I1 AS [value] FROM t
UNION ALL SELECT ID, 2, I2 FROM t
UNION ALL SELECT ID, 3, I3 FROM t
) AS t WHERE value IS NOT NULL ORDER BY ID, col;
以下のような結合を試してください:
select value from
(
select col1 as value from TestTable
union
select col2 as value from TestTable
union
select col3 as value from TestTable
) tt where value is not null