SQL транспонировать полную таблицу

Мне нужно сделать следующее транспонирование в MS SQL

от:

Day  A  B 
---------
Mon  1  2
Tue  3  4
Wed  5  6
Thu  7  8
Fri  9  0

К следующему:

Value Mon Tue Wed Thu Fri 
--------------------------
A      1   3   5   7   9
B      2   4   6   8   0

Я понимаю, как это сделать с PIVOT, когда есть только один столбец (A), но я не могу понять, как это сделать, когда нужно транспонировать несколько столбцов (A, B,...)

Пример кода для транспонирования:

select LEFT(datename(dw,datetime),3) as DateWeek, 
  sum(ACalls) as A, 
  Sum(BCalls) as B 
from DataTable
group by LEFT(datename(dw,datetime),3)

Структура таблицы:

Column DataType
DateTime Datetime
ACalls int
BCalls int

Любая помощь будет высоко ценится.


person Selrac    schedule 08.03.2013    source источник


Ответы (1)


Чтобы преобразовать данные в желаемый результат, вам потребуется использовать оба UNPIVOT и PIVOT.

Функция UNPIVOT берет столбцы A и B и преобразует результаты в строки. Затем вы будете использовать функцию PIVOT для преобразования значений day в столбцы:

select *
from
(
  select day, col, value
  from yourtable
  unpivot
  (
    value
    for col in (A, B)
  ) unpiv
) src
pivot
(
  max(value)
  for day in (Mon, Tue, Wed, Thu, Fri)
) piv

См. SQL Fiddle с демонстрацией.

Если вы используете SQL Server 2008+, вы можете использовать CROSS APPLY с VALUES, чтобы развернуть данные. Ваш код будет изменен на следующее:

select *
from
(
  select day, col, value
  from yourtable
  cross apply
  (
    values ('A', A),('B', B)
  ) c (col, value)
) src
pivot
(
  max(value)
  for day in (Mon, Tue, Wed, Thu, Fri)
) piv

См. SQL Fiddle с демонстрацией.

Отредактируйте № 1, применив текущий запрос к приведенному выше решению, вы будете использовать что-то похожее на это:

select *
from
(
  select LEFT(datename(dw,datetime),3) as DateWeek,
    col, 
    value
  from DataTable 
  cross apply 
  (
    values ('A', ACalls), ('B', BCalls)
  ) c (col, value)
) src
pivot
(
  sum(value)
  for dateweek in (Mon, Tue, Wed, Thu, Fri)
) piv
person Taryn    schedule 08.03.2013
comment
Спасибо за быстрый ответ. Мне не удается выполнить разворот для следующего запроса: выберите LEFT (datename (dw, datetime), 3) как DateWeek, SUM (ACalls) как A, SUM (BCalls) как B из группы _online_interval_data с помощью LEFT (datename (dw ,datetime), 3) Unpivot (= Неправильный синтаксис рядом с ключевым словом «Unpivot») - person Selrac; 08.03.2013
comment
Я использую SQL2008 R2. Та же ошибка проблемы с перекрестным применением --> выберите LEFT (datename (dw, datetime), 3) как DateWeek, SUM (ACalls) как A, SUM (BCalls) как B из группы данных по LEFT (datename (dw, datetime), 3) перекрестное применение (= неправильный синтаксис рядом с ключевым словом «крест») - person Selrac; 08.03.2013
comment
@user2148939 user2148939 Я не понимаю тот код, который вы разместили. Пожалуйста, отредактируйте исходный пост, указав структуру таблицы, а затем код, который вы используете. - person Taryn; 08.03.2013
comment
@user2148939 user2148939 Посмотрите мое редактирование о том, как вы включите свой текущий запрос в решение. - person Taryn; 08.03.2013
comment
Да, да!! Спасибо!! Я предполагаю, что если вам нужно больше столбцов, вам нужно добавить больше значений значений ('A', ACalls), ('B', BCalls), ('C', DCalls),... Правильно? - person Selrac; 08.03.2013
comment
@user2148939 user2148939 Да, верно. Вы просто добавите больше столбцов в файл VALUES. :) - person Taryn; 08.03.2013
comment
Столбец «col», кажется, упорядочивается в алфавитном порядке. Как вы можете изменить порядок убывания, например C, B, A или другой порядок, например A, C, B? - person Selrac; 09.03.2013
comment
Вы просто добавите ORDER BY col DESC в конце SQL. После ) piv - person Taryn; 09.03.2013
comment
Но как насчет того, если вы хотите еще один заказ. Например, если «col» — это названия месяцев. Вы не хотите, чтобы они были упорядочены, как апрель, август, декабрь,... Вы хотите, чтобы они были упорядочены, как январь, февраль, март,... Как вы можете сохранить этот порядок? - person Selrac; 09.03.2013
comment
@Selrac Пожалуйста, задайте новый вопрос с более подробной информацией о проблеме. Это будет проще, чем ходить туда-сюда по комментариям. :) - person Taryn; 09.03.2013