2013-04-02 9 views
9

ich die folgenden Beispieldaten haben:SQL Server 2012 PIVOT ohne Aggregat

Id Name  Category 
----------------------- 
1  Joe  A 
2  Joe  B 
3  Joe  D 
4  Mary  A 
5  Mary  C 
6  Mary  D 

Ich möchte die Kategorien zeigen, eine Person so mögen gehört:

Name CategoryA CategoryB CategoryC CategoryD 
-------------------------------------------------- 
Joe  X   X      X 
Mary  X      X   X 

1 und 0 verwendet werden könnten, anstelle von X und Leerzeichen.

Das riecht nach einer PIVOT-Frage für mich.

+0

möglich Duplikat [Get ROWS als Spalten (SQL Server dynamische PIVOT Abfrage) ] (http://stackoverflow.com/questions/12074939/get-rows-as-columns-sql-server-dynamic-pivot-query) – RichardTheKiwi

Antwort

25

Es gibt mehrere Möglichkeiten, wie Sie die Daten transformieren können. Einige verwenden eine Aggregatfunktion und andere nicht. Aber auch wenn Sie einen String schwenken, können Sie trotzdem ein Aggregat anwenden.

Aggregate mit CASE:

select name, 
    max(case when category = 'A' then 'X' else '' end) CategoryA, 
    max(case when category = 'B' then 'X' else '' end) CategoryB, 
    max(case when category = 'C' then 'X' else '' end) CategoryC, 
    max(case when category = 'D' then 'X' else '' end) CategoryD 
from yourtable 
group by name 

Siehe SQL Fiddle with Demo

Static Pivot:

können Sie immer noch die PIVOT Funktion verwenden, um die Daten zu transformieren, obwohl die Werte Strings sind. Wenn Sie eine bekannte Anzahl von Kategorien haben, dann können Sie hart Code die Abfrage:

select name, 
    coalesce(A, '') CategoryA, 
    coalesce(B, '') CategoryB, 
    coalesce(C, '') CategoryC, 
    coalesce(C, '') CategoryD 
from 
(
    select name, category, 'X' flag 
    from yourtable 
) d 
pivot 
(
    max(flag) 
    for category in (A, B, C, D) 
) piv 

Siehe SQL Fiddle with Demo.

Dynamische Pivot:

Wenn Sie eine unbekannte Anzahl von Kategorien haben, dann können Sie die dynamische SQL verwenden:

DECLARE @cols AS NVARCHAR(MAX), 
    @colsNull AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(category) 
        from yourtable 
        group by category 
        order by category 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colsNull = STUFF((SELECT ', coalesce(' + QUOTENAME(category)+', '''') as '+QUOTENAME('Category'+category) 
        from yourtable 
        group by category 
        order by category 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query = 'SELECT name, ' + @colsNull + ' 
       from 
      (
       select name, category, ''X'' flag 
       from yourtable 
      ) x 
      pivot 
      (
       max(flag) 
       for category in (' + @cols + ') 
      ) p ' 

execute(@query) 

SQL Fiddle with Demo See.

Mehrere Joins:

select c1.name, 
    case when c1.category is not null then 'X' else '' end as CategoryA, 
    case when c2.category is not null then 'X' else '' end as CategoryB, 
    case when c3.category is not null then 'X' else '' end as CategoryC, 
    case when c4.category is not null then 'X' else '' end as CategoryD 
from yourtable c1 
left join yourtable c2 
    on c1.name = c2.name 
    and c2.category = 'B' 
left join yourtable c3 
    on c1.name = c3.name 
    and c3.category = 'C' 
left join yourtable c4 
    on c1.name = c4.name 
    and c4.category = 'D' 
where c1.category = 'A' 

SQL Fiddle with Demo

Alle Anfragen sehen das Ergebnis geben:

| NAME | CATEGORYA | CATEGORYB | CATEGORYC | CATEGORYD | 
-------------------------------------------------------- 
| Joe |   X |   X |   |   X | 
| Mary |   X |   |   X |   X | 
+0

Heh ... Ich war wa tching die Antwort wird bearbeitet/verfeinert. Vielen Dank für die Bearbeitung der Antwort, um meine Anforderung, dass die Ergebnisse X/Leerzeichen enthalten, aufzunehmen. Dies gilt als akzeptierte Antwort. –

+2

@BlakeB. Ja, es heißt nicht vollständig die Frage zu lesen, tut mir leid. :) – Taryn

+0

Stellt sich heraus, dass die "Aggregat mit CASE" Version dieser Lösung viel besser als die PIVOT-Lösungen funktioniert. –