Zodra je een T-SQL Query typt wil je de data vaak groeperen. Vandaag kwam ik achter een grappig truukje bij het groeperen, de GROUP BY ALL mogelijkheid. Wellicht wat lastig uit te leggen wat het precies doet maar met een paar voorbeelden erbij zou het moeten lukken!
Met de GROUP BY ALL worden alle rijen gegroepeerd, ook al vallen ze buiten de dataset doordat je ze in de WHERE hebt gefilterd. Neem bijvoorbeeld onderstaande Query:
SELECT CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) AS WeekNummer, SUM(FIS.OrderQuantity) AS AantalOrders, SUM(FIS.SalesAmount) AS Omzet FROM FactInternetSales AS FIS LEFT OUTER JOIN DimTime AS DT ON FIS.OrderDateKey = DT.TimeKey WHERE ProductKey = 1 GROUP BY CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) ORDER BY CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) |
Deze dataset levert alle weeknummers op met daarachter de omzet voor Product 1. Als er geen omzet in een week te vinden is wordt de week ook niet getoond.
Voegen we de GROUP BY ALL toe………
SELECT CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) AS WeekNummer, SUM(FIS.OrderQuantity) AS AantalOrders, SUM(FIS.SalesAmount) AS Omzet FROM FactInternetSales AS FIS LEFT OUTER JOIN DimTime AS DT ON FIS.OrderDateKey = DT.TimeKey WHERE ProductKey = 1 GROUP BY ALL CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) ORDER BY CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) |
……dan krijg je ook de weken te zien die in de factinternetsales voorkomen maar waar geen omzet voor product 1 gevonden is:
Zetten we in de WHERE nog een extra regeltje (jaar > 2001)….
SELECT CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) AS WeekNummer, SUM(FIS.OrderQuantity) AS AantalOrders, SUM(FIS.SalesAmount) AS Omzet FROM FactInternetSales AS FIS LEFT OUTER JOIN DimTime AS DT ON FIS.OrderDateKey = DT.TimeKey WHERE ProductKey = 1 AND DT.CalendarYear > 2001 GROUP BY ALL CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) ORDER BY CAST(DT.CalendarYear AS INT) * 100 + CAST(DT.WeekNumberOfYear AS INT) |
…. dan krijg je wel alle weken uit 2001 te zien maar zul je NULL vinden in de overige kolommen. Dit betekent niet dat de waarde leeg is maar dat de waarde niet wordt weergegeven (lekker verwarrend…).