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/… Можливо, буде корисно;)
Пато

Ви можете побачити це посилання, якщо кількість відокремлених елементів невідоме, тобто немає колонок після перемикання динамічно.
Зворот

Відповіді:


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 Чувак ... ти серйозно геній. Я б хотів, щоб я міг це знати раніше, замість того, щоб навчитися PIVOT!
ashes999

@ Silmaril89 припускають, що назва другого стовпця - "дані", а 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

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


Дякую за цю рідкісну, чітку відповідь. він негайно показує приклад та отримані набори даних
real_yggdrasil

Я знаю, що це по-старому, але це найяскравіша, найкраще проілюстрована кравна демонстрація.
Стен Шоу

52

Якщо ви спеціально хочете використовувати функцію PIVOT SQL Server, то це має спрацювати, якщо припустити, що два оригінальні стовпці називаються 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

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])
 )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.