SQL Server: przykłady danych PIVOTing String

125

Próbuję znaleźć kilka prostych przykładów SQL Server PIVOT. Większość przykładów, które znalazłem, dotyczy liczenia lub sumowania liczb. Chcę tylko obrócić niektóre dane ciągów. Na przykład mam zapytanie zwracające następujący kod.

Action1 VIEW  
Action1 EDIT  
Action2 VIEW  
Action3 VIEW  
Action3 EDIT  

Chciałbym użyć PIVOT (jeśli to możliwe), aby uzyskać takie wyniki:

Action1 VIEW EDIT  
Action2 VIEW NULL  
Action3 VIEW EDIT  

Czy jest to w ogóle możliwe dzięki funkcji PIVOT?

Tim Cochran
źródło
Spójrz na ten link: dotnetgalactics.wordpress.com/2009/10/23/… Może być pomocny;)
Pato
Możesz zobaczyć ten link, jeśli liczba odrębnych elementów jest nieznana, co oznacza, że ​​liczba kolumn po przestawieniu jest dynamiczna. SQL Server Pivot: konwertowanie wierszy na kolumny za pomocą dynamicznego zapytania
maeenul,

Odpowiedzi:

165

Pamiętaj, że funkcja agregująca MAX będzie działać zarówno na tekście, jak i na liczbach. To zapytanie będzie wymagało tylko jednorazowego przeskanowania tabeli.

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
John Hubert
źródło
+1 Koleś ... jesteś naprawdę geniuszem. Żałuję, że nie mogłem wiedzieć o tym wcześniej, zamiast uczyć się, jak PIVOT!
popioły 999
@ Silmaril89 załóżmy, że nazwa drugiej kolumny to „dane”, a pierwsza to „Działanie”
Iman,
1
Czy jest jakiś powód, dla którego nie powinienem używać ...ELSE NULL END...zamiast ...ELSE '' END...?
pon.
15
Co jest szybsze, to czy PIVOT?
Robert Jeppesen
Whoah, właśnie rozwaliłeś mój umysł. Z tyłu głowy przyszło mi do głowy, że serwer SQL „powinien po prostu zrobić darnit!”, Ale pomyślałem, że nie da się tego zrobić. Wtedy to zobaczyłem.
David Hay
54

Konfiguracja stołu:

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');

Twój stół: SELECT action, view_edit FROM dbo.tbl

Twój stół

Zapytanie bez użycia 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

Zapytanie za pomocą 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

Wynik obu zapytań:
wprowadź opis obrazu tutaj

mxasim
źródło
Dzięki za tę rzadką, jasną odpowiedź. natychmiast pokazuje przykład i wynikające z niego
zbiory
Wiem, że to jest stare, ale jest to najwyraźniejsza, najlepiej ilustrowana demonstracja pivot, jaką widziałem.
Stan Shaw
52

Jeśli chcesz użyć funkcji PIVOT programu SQL Server, powinno to zadziałać, zakładając, że dwie oryginalne kolumny nazywają się act i cmd. (Nie jest to jednak takie ładne.)

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
Miles D.
źródło
6

Cóż, w przypadku twojej próbki i każdej z ograniczoną liczbą unikalnych kolumn powinno to wystarczyć.

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
źródło
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;
Vishwanath Dalvi
źródło
0

Miałem sytuację, w której analizowałem ciągi znaków, a pierwsze dwie pozycje tego ciągu byłyby nazwami pól standardu kodowania oświadczeń zdrowotnych. Więc usunąłbym ciągi znaków i uzyskał wartości dla F4, UR i UQ lub czegoś takiego. To było świetne w przypadku jednego rekordu lub kilku rekordów dla jednego użytkownika. Ale kiedy chciałem zobaczyć setki rekordów i wartości dla wszystkich użytkowników, musiał to być PIVOT. Było to wspaniałe zwłaszcza w przypadku eksportowania wielu płyt do doskonałości. Konkretne żądanie raportowania, które otrzymałem, brzmiało: „za każdym razem, gdy ktoś składał wniosek dotyczący Benadrylu, jaką wartość podał w polach F4, UR i UQ. Miałem APLIKACJĘ ZEWNĘTRZNĄ, która utworzyła ColTitle i pola wartości poniżej

PIVOT(
  min(value)
  FOR ColTitle in([F4], [UR], [UQ])
 )
1994 Nerd
źródło