SQL Server: примеры данных PIVOTing String

125

Пытаюсь найти несколько простых примеров PIVOT SQL Server. Большинство примеров, которые я нашел, связаны с подсчетом или суммированием чисел. Я просто хочу развернуть некоторые строковые данные. Например, у меня есть запрос, возвращающий следующее.

Action1 VIEW  
Action1 EDIT  
Action2 VIEW  
Action3 VIEW  
Action3 EDIT  

Я хотел бы использовать PIVOT (если даже возможно), чтобы получить такие результаты:

Action1 VIEW EDIT  
Action2 VIEW NULL  
Action3 VIEW EDIT  

Возможно ли это даже с помощью функции PIVOT?

Тим Кокран
источник
Взгляните на эту ссылку: dotnetgalactics.wordpress.com/2009/10/23/… Может быть полезно;)
Пато,
Вы можете увидеть эту ссылку, если количество отдельных элементов неизвестно, то есть ни один из столбцов после поворота не является динамическим. SQL Server Pivot: преобразование строк в столбцы с помощью динамического запроса
майнул

Ответы:

165

Помните, что агрегатная функция MAX будет работать как с текстом, так и с числами. Этот запрос потребует только однократного сканирования таблицы.

SELECT Action,
       MAX( CASE data WHEN 'View' THEN data ELSE '' END ) ViewCol, 
       MAX( CASE data WHEN 'Edit' THEN data ELSE '' END ) EditCol
 FROM t
 GROUP BY Action
Джон Хьюберт
источник
+1 Чувак ... ты серьезно гений. Хотел бы я узнать это раньше, вместо того, чтобы научиться ПИВОТ!
ashes999
@ Silmaril89 предполагает, что имя 2-го столбца, о котором идет речь, - «данные», а 1-й столбец - «Действие»
Иман
1
Есть ли причина, по которой мне не следует использовать ...ELSE NULL END...вместо ...ELSE '' END...?
мес.
15
Что быстрее, это или PIVOT?
Роберт Джеппесен,
Ого, ты просто взорвал мне голову. В глубине души у меня было представление о том, что я думал, что SQL-сервер «должен просто делать чертовски!», Но думал, что это невозможно. Потом я увидел это.
Дэвид Хэй
54

Настройка стола:

CREATE TABLE dbo.tbl (
    action VARCHAR(20) NOT NULL,
    view_edit VARCHAR(20) NOT NULL
);

INSERT INTO dbo.tbl (action, view_edit)
VALUES ('Action1', 'VIEW'),
       ('Action1', 'EDIT'),
       ('Action2', 'VIEW'),
       ('Action3', 'VIEW'),
       ('Action3', 'EDIT');

Ваш стол: SELECT action, view_edit FROM dbo.tbl

Ваш стол

Запрос без использования PIVOT:

SELECT Action, 
[View] = (Select view_edit FROM tbl WHERE t.action = action and view_edit = 'VIEW'),
[Edit] = (Select view_edit FROM tbl WHERE t.action = action and view_edit = 'EDIT')
FROM tbl t
GROUP BY Action

Запрос с использованием PIVOT:

SELECT [Action], [View], [Edit] FROM
(SELECT [Action], view_edit FROM tbl) AS t1 
PIVOT (MAX(view_edit) FOR view_edit IN ([View], [Edit]) ) AS t2

Результат обоих запросов:
введите описание изображения здесь

mxasim
источник
Спасибо за этот редкий и ясный ответ. он сразу показывает пример и результирующие наборы данных
real_yggdrasil
Я знаю, что это устарело, но это самая ясная, лучше всего иллюстрированная демонстрация поворота, которую я видел.
Стэн Шоу
52

Если вы специально хотите использовать функцию SQL Server PIVOT, это должно работать, если ваши два исходных столбца называются act и cmd. (Хотя это не так красиво.)

SELECT act AS 'Action', [View] as 'View', [Edit] as 'Edit'
FROM (
    SELECT act, cmd FROM data
) AS src
PIVOT (
    MAX(cmd) FOR cmd IN ([View], [Edit])
) AS pvt
Майлз Д
источник
6

Что ж, для вашего образца и любого с ограниченным количеством уникальных столбцов это должно сработать.

select 
    distinct a,
    (select distinct t2.b  from t t2  where t1.a=t2.a and t2.b='VIEW'),
    (select distinct t2.b from t t2  where t1.a=t2.a and t2.b='EDIT')
from t t1
vzczc
источник
5
With pivot_data as
(
select 
action, -- grouping column
view_edit -- spreading column
from tbl
)
select action, [view], [edit]
from   pivot_data
pivot  ( max(view_edit) for view_edit in ([view], [edit]) ) as p;
Вишванатх Далви
источник
0

У меня была ситуация, когда я анализировал строки, и первые две позиции рассматриваемой строки были бы именами полей стандарта кодирования медицинских требований. Поэтому я бы вырезал строки и получил значения для F4, UR и UQ или еще чего. Это было здорово для одной записи или нескольких записей для одного пользователя. Но когда я хотел увидеть сотни записей и значений для всех пользователей, мне потребовался PIVOT. Это было замечательно, особенно для экспорта большого количества записей, чтобы преуспеть. Конкретный запрос на отчет, который я получил, заключался в следующем: «Каждый раз, когда кто-то подавал заявку на Benadryl, какое значение они отправляли в поля F4, UR и UQ. У меня было ВНЕШНЕЕ ПРИЛОЖЕНИЕ, которое создавало поля ColTitle и значения ниже.

PIVOT(
  min(value)
  FOR ColTitle in([F4], [UR], [UQ])
 )
1994Nerd
источник