Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server-Abfrage:Zeilen machen Spalten (Pivot?)

Das Pivotieren ist ähnlich wie das Gruppieren. Sie könnten es als begrenzte Gruppierung mit einem „Spezialeffekt“ ansehen. Die Einschränkung besteht darin, dass es nur eine aggregierte Spalte geben darf. (In einer normalen GROUP BY-Abfrage können Sie natürlich mehr als eine haben.) Und mit dem 'Spezialeffekt' meine ich natürlich, dass eine der anderen Spalten (und wieder nur eine) in mehrere Spalten umgewandelt wird.

Nehmen wir Ihre GROUP BY-Abfrage als Beispiel. Sie haben drei Spalten in der Ausgabe. Einer von ihnen, Count , ist genau die Spalte, die aggregierte Informationen enthält. Das ist derjenige, der in einer PIVOT-Abfrage über mehrere Spalten verteilt wäre. Eine weitere Spalte, Priority , ist eine der beiden anderen Spalten, nach denen die Ergebnisse gruppiert werden, und auch diejenige, die geschwenkt werden muss. Schließlich EntryDate ist die andere GROUP BY-Spalte. Es soll einfach so bleiben wie es ist, weil es nicht direkt an der Pivotisierung teilnimmt.

Sehen wir uns nun an, wie Ihr Haupt-SELECT Schritt für Schritt von einer gewöhnlichen GROUP BY-Abfrage in eine PIVOT-Abfrage umgewandelt wird:

  1. Da die Gruppierung in einer PIVOT-Abfrage impliziert ist, wird die GROUP BY-Klausel entfernt. Stattdessen wird eine PIVOT-Klausel eingeführt.

  2. Die Count Der Ausdruck der Spalte wird von der SELECT-Klausel in die PIVOT-Klausel verschoben.

  3. Die Aufteilung der Priority Spalte ist in der PIVOT-Klausel definiert.

  4. Die Priority und Count Spalten in der SELECT-Klausel werden durch die Liste der Spalten ersetzt, die in der PIVOT-Klausel definiert sind.

  5. Das EntryDate Spalte bleibt in der SELECT-Klausel unverändert.

Und hier ist die resultierende Abfrage mit Kommentaren, die jeden Teil der oben beschriebenen Transformation markieren:

WITH TATH(Priority, EntryDate) AS 
(
    SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate
      FROM TicketAssignment TA, TicketHeader TH 
     WHERE TA.TicketID = TH.TicketID   
       AND TA.Company = 'IT'
       AND TA.CurrentRole IN ('SA1B','SA1C','SDA')
) 
SELECT
  convert(varchar(10), EntryDate,103) as EntryDate,                       -- #5
  [0] AS Priority0, [1] AS Priority1, [2] AS Priority2, [3] AS Priority3  -- #4
FROM TATH
PIVOT (                                                                   -- #1
  COUNT(*)                                                                -- #2
  FOR Priority IN ([0], [1], [2], [3])                                    -- #3
) p

/*  -- your original main query, for comparison
SELECT
  Priority,                                                               -- #4
  convert(varchar(10),                                                    -- #5
  EntryDate,103) as EntryDate, COUNT(*) AS Count                          -- ##2&4
FROM TATH 
GROUP BY Priority, EntryDate                                              -- #1
*/

Es gibt eine zusätzliche Anmerkung zur Spaltenliste in der PIVOT-Klausel. Zunächst müssen Sie verstehen, dass die Ergebnismenge einer SQL-Abfrage in Bezug auf die Anzahl der Spalten und deren Namen festgelegt werden soll. Das bedeutet, dass Sie alle transformierten Spalten, die Sie in der Ausgabe sehen möchten, explizit aufzählen müssen. Die Namen werden von den Werten der zu pivotierenden Spalte abgeleitet, sollten aber als Namen angegeben werden , nicht als Werte. Deshalb sehen Sie eckige Klammern um die aufgeführten Nummern. Da Zahlen selbst nicht die Regeln für reguläre Bezeichner , müssen sie getrennt werden.

Sie können auch sehen, dass Sie Pivot-Spalten in der SELECT-Klausel wie jede andere Spalte oder jeden anderen Ausdruck aliasieren können. Am Ende müssen Sie also nicht bei der bedeutungslosen 0 landen , 1 usw. Bezeichner und stattdessen können Sie diesen Spalten beliebige Namen zuweisen.

Wenn Sie möchten, dass die Anzahl und/oder Namen der Pivot-Spalten dynamisch sind, müssen Sie die Abfrage dynamisch erstellen, d. h. zuerst die Namen sammeln und sie dann in eine Zeichenfolge integrieren, die den Rest enthält Abfrage und rufen Sie die letzte Abfrage mit EXEC () auf oder EXEC sp_executesql . Sie können diese Website durchsuchen für weitere Informationen zum dynamischen Pivotieren.