sql >> Database >  >> RDS >> Sqlserver

SQL Server-query:rijen maken kolommen (Pivot?)

Draaien lijkt veel op groeperen. Je zou het kunnen zien als een beperkte groepering met een ‘special effect’. De beperking is dat er maar één geaggregeerde kolom kan zijn. (In de normale GROUP BY-query kun je er natuurlijk meer dan één hebben.) En met het 'speciale effect' bedoel ik natuurlijk dat een van de andere kolommen (en, nogmaals, slechts één) wordt omgezet in meerdere kolommen.

Laten we uw GROUP BY-query als voorbeeld nemen. Je hebt drie kolommen in de uitvoer. Een van hen, Count , is de kolom die geaggregeerde informatie bevat. Dat is degene die zou worden verspreid over meerdere kolommen in een PIVOT-query. Een andere kolom, Priority , is een van de twee andere kolommen waarop de resultaten zijn gegroepeerd en ook degene die moet worden gedraaid. Ten slotte, EntryDate is de andere kolom GROUP BY. Het moet gewoon blijven zoals het is, omdat het niet direct deelneemt aan het draaien.

Laten we nu eens kijken hoe uw belangrijkste SELECT stap voor stap wordt omgezet van een gebruikelijke GROUP BY-query in een PIVOT-query:

  1. Aangezien groeperen is geïmpliceerd in een PIVOT-query, wordt de GROUP BY-component verwijderd. In plaats daarvan wordt een PIVOT-clausule geïntroduceerd.

  2. De Count de uitdrukking van de kolom wordt verplaatst van de SELECT-component naar de PIVOT-component.

  3. De splitsing van de Priority kolom is gedefinieerd in de PIVOT-clausule.

  4. De Priority en Count kolommen in de SELECT-component worden vervangen door de lijst met kolommen die zijn gedefinieerd in de PIVOT-component.

  5. De EntryDate kolom blijft ongewijzigd in de SELECT-component.

En hier is de resulterende vraag, met opmerkingen die elk deel van de hierboven beschreven transformatie markeren:

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
*/

Er is nog een extra opmerking over de kolomlijst in de PIVOT-component. Allereerst moet u begrijpen dat de resulterende set van een SQL-query verondersteld wordt vast te zijn in termen van het aantal kolommen en hun namen. Dat betekent dat u expliciet alle getransformeerde kolommen moet opsommen die u in de uitvoer wilt zien. De namen zijn afgeleid van de waarden van de kolom die wordt gedraaid, maar ze moeten worden opgegeven als namen , niet als waarden. Daarom ziet u vierkante haken rond de vermelde nummers. Aangezien nummers zelf niet voldoen aan de regels voor gewone identifiers , ze moeten worden gescheiden.

U kunt ook zien dat u gedraaide kolommen in de SELECT-component kunt aliassen, net als elke andere kolom of uitdrukking. Dus uiteindelijk hoef je niet te eindigen met de nietszeggende 0 , 1 etc. identifiers en in plaats daarvan kunt u die kolommen elke gewenste naam toewijzen.

Als u wilt dat het aantal en/of de namen van de gedraaide kolommen dynamisch zijn, moet u de query dynamisch opbouwen, d.w.z. eerst de namen verzamelen en ze vervolgens opnemen in een tekenreeks die de rest van de query en roep de laatste query op met EXEC () of EXEC sp_executesql . U kunt op deze site zoeken voor meer informatie over dynamisch draaien.




  1. Verwijder alle spaties uit een string in SQL Server

  2. ORA-28000:het account is vergrendeld, fout wordt vaak weergegeven

  3. SQL Server-prestaties voor het wijzigen van de tabel wijzigen van het gegevenstype van de wijziging van de kolom

  4. MaxMind's GeoLite2 importeren naar MySQL