SQL: реальная Транспонировка


Я знаю о pivot и unpivot. Это не то, чего я хочу. Сводные и непивотные агрегированные данные, но это не то, что мне нужно.

Подумайте о таблице как о матрице (линейная алгебра). Если я начну с матрицы m x n, я хочу преобразовать эту матрицу (таблицу) в матрицу n x M. Я хочу истинную транспозицию .

Как я могу сделать это в SQL?

Например, если у меня есть:

1  2  3
1  2  4
6  7  8
3  2  1
3  9  1

Тогда результат должен быть:

1  1  6  3  3
2  2  7  2  9
3  4  8  1  1

Обратите внимание, что число строк становится количество колонок, и наоборот. Также обратите внимание, что я не сгруппировал и не агрегировал какие-либо данные. Каждое отдельное значение, присутствующее в источнике, присутствует в результате,и их координаты x-y были заменены.

1 5

1 ответ:

Я не уверен, почему вы думаете, что не можете достичь этого с помощью UNPIVOT и PIVOT:

select [1], [2], [3], [4], [5]
from 
(
  select *
  from
  (
    select col1, col2, col3,
      row_number() over(order by col1) rn
    from yourtable
  ) x
  unpivot
  (
    val for col in (col1, col2, col3)
  ) u
) x1
pivot
(
  max(val)
  for rn in ([1], [2], [3], [4], [5])
) p

Смотрите SQL Fiddle with Demo. Это также может быть выполнено динамически, если это необходимо.

Edit, если порядок столбцов должен быть сохранен, то вы можете использовать что-то вроде этого, которое применяет row_number() без использования order by на одном из столбцов в вашей таблице (вот статья об использовании недетерминированных номеров строк):

select [1], [2], [3], [4], [5]
from 
(
  select *
  from
  (
    select col1, col2, col3,
      row_number() 
        over(order by (select 1)) rn
    from yourtable
  ) x
  unpivot
  (
    val for col in (col1, col2, col3)
  ) u
) x1
pivot
(
  max(val)
  for rn in ([1], [2], [3], [4], [5])
) p;

См. SQL Fiddle with Демо