Подтвердить что ты не робот

Выберите значения из нескольких столбцов в один столбец

У меня есть таблица в базе данных, в которой есть 9 столбцов, содержащих один и тот же тип данных, эти значения разрешены как null. Мне нужно выбрать каждое из ненулевых значений в один столбец значений, который не заботится об идентичности строки, из которой они возникли.

Итак, для таблицы, которая выглядит так:

+---------+------+--------+------+
|   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. Есть ли лучший способ достижения этого, чем выбор значения каждого столбца по очереди, из каждой строки и вставка ненулевых значений в результаты?

4b9b3361

Ответ 1

Вы можете использовать функцию 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

Ответ 2

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;

Ответ 3

Попробуйте соединение, как показано ниже:

    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