Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
SQL-databas i Microsoft Fabric
GROUPING_ID Är en funktion som beräknar nivån av gruppering.
GROUPING_ID kan endast användas i SELECT <select> listan, HAVING, eller ORDER BY klausuler när GROUP BY anges är specificerad.
Transact-SQL syntaxkonventioner
Syntax
GROUPING_ID ( <column_expression> [ , ...n ] )
Arguments
<column_expression>
En column_expression i en SELECT - GROUP BY-sats .
Returtyper
int
Anmärkningar
De GROUPING_ID <column_expression> måste exakt matcha uttrycket i listan GROUP BY . Till exempel, om du grupperar efter DATEPART (yyyy, <column name>), använd GROUPING_ID (DATEPART (yyyy, <column name>)); eller om du grupperar efter <column name>, använd GROUPING_ID (<column name>).
Jämför GROUPING_ID() med GROUPING()
GROUPING_ID (<column_expression> [ , ...n ]) indata motsvarar avkastningen GROUPING (<column_expression>) för varje kolumn i dess kolumnlistor i varje utdatarad, som en sträng av ettor. och nollor.
GROUPING_ID tolkar den strängen som ett bas-2-tal och returnerar motsvarande heltal.
Till exempel, betrakta följande påstående:
SELECT a, b, c, SUM(d),
GROUPING_ID(a, b, c)
FROM T
GROUP BY <group_by_list>
Denna tabell visar GROUPING_ID() in- och utdatavärdena.
| Sammanlagda kolumner | GROUPING_ID (a, b, c) indata = GRUPPERING(a) + GRUPPERING(b) + GRUPPERING(c) | GROUPING_ID() utgång |
|---|---|---|
a |
100 |
4 |
b |
010 |
2 |
c |
001 |
1 |
ab |
110 |
6 |
ac |
101 |
5 |
bc |
011 |
3 |
abc |
111 |
7 |
Teknisk definition av GROUPING_ID()
Varje GROUPING_ID argument måste vara ett element i listan GROUP BY .
GROUPING_ID() returnerar en heltalsbitmap vars lägsta n bitar kan vara belysta. En lit-bit indikerar att motsvarande argument inte är en grupperingskolumn för den givna utdataraden. Den lägsta ordningens biten motsvarar argument n, och den n1-1 lägsta ordningens biten motsvarar argument 1.
GROUPING_ID()-ekvivalenter
För en enskild grupperingsfråga GROUPING (<column_expression>) är ekvivalent med GROUPING_ID (<column_expression>), och båda returnerar 0.
Till exempel är följande påståenden ekvivalenta:
Påstående A
SELECT GROUPING_ID(A, B)
FROM T
GROUP BY CUBE(A, B)
Uttalande B
SELECT 3 FROM T GROUP BY ()
UNION ALL
SELECT 1 FROM T GROUP BY A
UNION ALL
SELECT 2 FROM T GROUP BY B
UNION ALL
SELECT 0 FROM T GROUP BY A, B
Examples
Kodexemplen i den här artikeln använder AdventureWorks2025- eller AdventureWorksDW2025-exempeldatabasen, som du kan ladda ned från startsidan Microsoft SQL Server Samples och Community Projects.
A. Använd GROUPING_ID för att identifiera grupperingsnivåer
Följande exempel returnerar antalet anställda efter Name och Title, samt företagets totala antal i databasen AdventureWorks2025 .
GROUPING_ID() används för att skapa ett värde för varje rad i kolumnen Title som identifierar dess aggregeringsnivå.
SELECT D.Name,
CASE
WHEN GROUPING_ID(D.Name, E.JobTitle) = 0 THEN E.JobTitle
WHEN GROUPING_ID(D.Name, E.JobTitle) = 1 THEN N'Total: ' + D.Name
WHEN GROUPING_ID(D.Name, E.JobTitle) = 3 THEN N'Company Total:'
ELSE N'Unknown'
END AS N'Job Title',
COUNT(E.BusinessEntityID) AS N'Employee Count'
FROM HumanResources.Employee E
INNER JOIN HumanResources.EmployeeDepartmentHistory DH
ON E.BusinessEntityID = DH.BusinessEntityID
INNER JOIN HumanResources.Department D
ON D.DepartmentID = DH.DepartmentID
WHERE DH.EndDate IS NULL
AND D.DepartmentID IN (12, 14)
GROUP BY ROLLUP(D.Name, E.JobTitle);
B. Använd GROUPING_ID för att filtrera en resultatmängd
Grundläggande exempel
I följande kod, för att endast returnera rader som har antal anställda efter titel, ta bort kommentarstecknen från HAVING GROUPING_ID(D.Name, E.JobTitle) = 0;. För att returnera endast rader med antal anställda per avdelning, ta bort kommentarstecknen från HAVING GROUPING_ID(D.Name, E.JobTitle) = 1;.
SELECT D.Name,
E.JobTitle,
GROUPING_ID(D.Name, E.JobTitle) AS [Grouping Level],
COUNT(E.BusinessEntityID) AS [Employee Count]
FROM HumanResources.Employee AS E
INNER JOIN HumanResources.EmployeeDepartmentHistory AS DH
ON E.BusinessEntityID = DH.BusinessEntityID
INNER JOIN HumanResources.Department AS D
ON D.DepartmentID = DH.DepartmentID
WHERE DH.EndDate IS NULL
AND D.DepartmentID IN (12, 14)
GROUP BY ROLLUP(D.Name, E.JobTitle)
-- HAVING GROUPING_ID(D.Name, E.JobTitle) = 0; -- All titles
-- HAVING GROUPING_ID(D.Name, E.JobTitle) = 1; -- Group by Name;
Här är den ofiltrerade resultatuppsättningen.
| Namn | Titel | Grupperingsnivå | Antal anställda | Namn |
|---|---|---|---|---|
| Dokumentkontroll | Kontrollspecialist | 0 | 2 | Dokumentkontroll |
| Dokumentkontroll | Dokumentkontrollassistent | 0 | 2 | Dokumentkontroll |
| Dokumentkontroll | Dokumentkontrollhanterare | 0 | 1 | Dokumentkontroll |
| Dokumentkontroll | NULL |
1 | 5 | Dokumentkontroll |
| Faciliteter och underhåll | Administrativ assistent för anläggningar | 0 | 1 | Faciliteter och underhåll |
| Faciliteter och underhåll | Fastighetschef | 0 | 1 | Faciliteter och underhåll |
| Faciliteter och underhåll | Vaktmästare | 0 | 4 | Faciliteter och underhåll |
| Faciliteter och underhåll | Underhållschef | 0 | 1 | Faciliteter och underhåll |
| Faciliteter och underhåll | NULL |
1 | 7 | Faciliteter och underhåll |
NULL |
NULL |
3 | 12 | NULL |
Komplext exempel
Följande exempel använder GROUPING_ID() för att filtrera en resultatmängd som innehåller flera grupperingsnivåer efter grupperingsnivå. Liknande kod kan användas för att skapa en vy med flera grupperingsnivåer, samt en lagrad proprodur som anropar vyn genom att skicka en parameter som filtrerar vyn efter grupperingsnivå.
DECLARE @Grouping NVARCHAR(50);
DECLARE @GroupingLevel SMALLINT;
SET @Grouping = N'CountryRegionCode Total';
SELECT @GroupingLevel = (
CASE @Grouping
WHEN N'Grand Total' THEN 15
WHEN N'SalesPerson Total' THEN 14
WHEN N'Store Total' THEN 13
WHEN N'Store SalesPerson Total' THEN 12
WHEN N'CountryRegionCode Total' THEN 11
WHEN N'Group Total' THEN 7
ELSE N'Unknown'
END
);
SELECT T.[Group],
T.CountryRegionCode,
S.Name AS N'Store',
(
SELECT P.FirstName + ' ' + P.LastName
FROM Person.Person AS P
WHERE P.BusinessEntityID = H.SalesPersonID
) AS N'Sales Person',
SUM(TotalDue) AS N'TotalSold',
CAST(GROUPING(T.[Group]) AS CHAR(1)) + CAST(GROUPING(T.CountryRegionCode) AS CHAR(1)) + CAST(GROUPING(S.Name) AS CHAR(1)) + CAST(GROUPING(H.SalesPersonID) AS CHAR(1)) AS N'GROUPING base-2',
GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) AS N'GROUPING_ID',
CASE
WHEN GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) = 15
THEN N'Grand Total'
WHEN GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) = 14
THEN N'SalesPerson Total'
WHEN GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) = 13
THEN N'Store Total'
WHEN GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) = 12
THEN N'Store SalesPerson Total'
WHEN GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) = 11
THEN N'CountryRegionCode Total'
WHEN GROUPING_ID((T.[Group]), (T.CountryRegionCode), (S.Name), (H.SalesPersonID)) = 7
THEN N'Group Total'
ELSE N'Error'
END AS N'Level'
FROM Sales.Customer AS C
INNER JOIN Sales.Store AS S
ON C.StoreID = S.BusinessEntityID
INNER JOIN Sales.SalesTerritory AS T
ON C.TerritoryID = T.TerritoryID
INNER JOIN Sales.SalesOrderHeader AS H
ON C.CustomerID = H.CustomerID
GROUP BY GROUPING SETS(
(S.Name,H.SalesPersonID),
(H.SalesPersonID),
(S.Name),
(T.[Group]),
(T.CountryRegionCode),
()
)
HAVING GROUPING_ID(
(T.[Group]),
(T.CountryRegionCode),
(S.Name),
(H.SalesPersonID)
) = @GroupingLevel
ORDER BY
GROUPING_ID(S.Name, H.SalesPersonID),
GROUPING_ID(
(T.[Group]),
(T.CountryRegionCode),
(S.Name),
(H.SalesPersonID)
) ASC;
C. Använd GROUPING_ID() med ROLLUP och CUBE för att identifiera grupperingsnivåer
Koden i följande exempel visar att man använder GROUPING() för att beräkna kolumnen Bit Vector(base-2) .
GROUPING_ID() används för att beräkna motsvarande Integer Equivalent kolumn. Kolumnordningen i GROUPING_ID() funktionen är motsatsen till kolumnordningen hos de kolumner som är sammanfogade av GROUPING() funktionen.
I dessa exempel GROUPING_ID() används för att skapa ett värde för varje rad i kolumnen Grouping Level för att identifiera nivån av gruppering. Grupperingsnivåer är inte alltid en på varandra följande lista av heltal som börjar med 1 (0, 1, 2, ... n).
Anmärkning
GROUPING och GROUPING_ID kan användas i en HAVING klausul för att filtrera en resultatmängd.
ROLLUP-exempel
I detta exempel visas inte alla grupperingsnivåer som de gör i följande CUBE exempel. Om ordningen på kolumnerna i ROLLUP listan ändras måste även nivåvärdena i Grouping Level kolumnen ändras.
SELECT DATEPART(yyyy, OrderDate) AS N'Year',
DATEPART(mm, OrderDate) AS N'Month',
DATEPART(dd, OrderDate) AS N'Day',
SUM(TotalDue) AS N'Total Due',
CAST(GROUPING(DATEPART(dd, OrderDate)) AS CHAR(1)) + CAST(GROUPING(DATEPART(mm, OrderDate)) AS CHAR(1)) + CAST(GROUPING(DATEPART(yyyy, OrderDate)) AS CHAR(1)) AS N'Bit Vector(base-2)',
GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) AS N'Integer Equivalent',
CASE
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 0
THEN N'Year Month Day'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 1
THEN N'Year Month'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 2
THEN N'not used'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 3
THEN N'Year'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 4
THEN N'not used'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 5
THEN N'not used'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 6
THEN N'not used'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 7
THEN N'Grand Total'
ELSE N'Error'
END AS N'Grouping Level'
FROM Sales.SalesOrderHeader
WHERE DATEPART(yyyy, OrderDate) IN (N'2007', N'2008')
AND DATEPART(mm, OrderDate) IN (1, 2)
AND DATEPART(dd, OrderDate) IN (1, 2)
GROUP BY ROLLUP(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate))
ORDER BY GROUPING_ID(DATEPART(mm, OrderDate), DATEPART(yyyy, OrderDate), DATEPART(dd, OrderDate)),
DATEPART(yyyy, OrderDate),
DATEPART(mm, OrderDate),
DATEPART(dd, OrderDate);
Här är en partiell resultatuppsättning.
| År | Månad | Day | Total förfallen | Bitvektor (bas-2) | Heltalsekvivalent | Grupperingsnivå |
|---|---|---|---|---|---|---|
| 2007 | 1 | 1 | 1497452.6066 | 000 | 0 | År Månad Dag |
| 2007 | 1 | 2 | 21772.3494 | 000 | 0 | År Månad Dag |
| 2007 | 2 | 1 | 2705653.5913 | 000 | 0 | År Månad Dag |
| 2007 | 2 | 2 | 21684.4068 | 000 | 0 | År Månad Dag |
| 2008 | 1 | 1 | 1908122.0967 | 000 | 0 | År Månad Dag |
| 2008 | 1 | 2 | 46458.0691 | 000 | 0 | År Månad Dag |
| 2008 | 2 | 1 | 3108771.9729 | 000 | 0 | År Månad Dag |
| 2008 | 2 | 2 | 54598.5488 | 000 | 0 | År Månad Dag |
| 2007 | 1 | NULL |
1519224.956 | 100 | 1 | Årsmånaden |
| 2007 | 2 | NULL |
2727337.9981 | 100 | 1 | Årsmånaden |
| 2008 | 1 | NULL |
1954580.1658 | 100 | 1 | Årsmånaden |
| 2008 | 2 | NULL |
3163370.5217 | 100 | 1 | Årsmånaden |
| 2007 | NULL |
NULL |
4246562.9541 | 110 | 3 | År |
| 2008 | NULL |
NULL |
5117950.6875 | 110 | 3 | År |
NULL |
NULL |
NULL |
9364513.6416 | 111 | 7 | Totalsumma |
CUBE-exempel
I detta exempel GROUPING_ID() används funktionen för att skapa ett värde för varje rad i kolumnen Grouping Level för att identifiera nivån på grupperingen.
Till skillnad från ROLLUP i det föregående exemplet CUBE ger den alla grupperingsnivåer. Om ordningen på kolumnerna i CUBE listan ändras måste även nivåvärdena i Grouping Level kolumnen ändras.
SELECT DATEPART(yyyy, OrderDate) AS N'Year',
DATEPART(mm, OrderDate) AS N'Month',
DATEPART(dd, OrderDate) AS N'Day',
SUM(TotalDue) AS N'Total Due',
CAST(GROUPING(DATEPART(dd, OrderDate)) AS CHAR(1)) + CAST(GROUPING(DATEPART(mm, OrderDate)) AS CHAR(1)) + CAST(GROUPING(DATEPART(yyyy, OrderDate)) AS CHAR(1)) AS N'Bit Vector(base-2)',
GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) AS N'Integer Equivalent',
CASE
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 0
THEN N'Year Month Day'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 1
THEN N'Year Month'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 2
THEN N'Year Day'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 3
THEN N'Year'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 4
THEN N'Month Day'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 5
THEN N'Month'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 6
THEN N'Day'
WHEN GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)) = 7
THEN N'Grand Total'
ELSE N'Error'
END AS N'Grouping Level'
FROM Sales.SalesOrderHeader
WHERE DATEPART(yyyy, OrderDate) IN (N'2007', N'2008')
AND DATEPART(mm, OrderDate) IN (1, 2)
AND DATEPART(dd, OrderDate) IN (1, 2)
GROUP BY CUBE(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate))
ORDER BY GROUPING_ID(DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate), DATEPART(dd, OrderDate)),
DATEPART(yyyy, OrderDate),
DATEPART(mm, OrderDate),
DATEPART(dd, OrderDate);
Här är en partiell resultatuppsättning.
| År | Månad | Day | Total förfallen | Bitvektor (bas-2) | Heltalsekvivalent | Grupperingsnivå |
|---|---|---|---|---|---|---|
| 2007 | 1 | 1 | 1497452.6066 | 000 | 0 | År Månad Dag |
| 2007 | 1 | 2 | 21772.3494 | 000 | 0 | År Månad Dag |
| 2007 | 2 | 1 | 2705653.5913 | 000 | 0 | År Månad Dag |
| 2007 | 2 | 2 | 21684.4068 | 000 | 0 | År Månad Dag |
| 2008 | 1 | 1 | 1908122.0967 | 000 | 0 | År Månad Dag |
| 2008 | 1 | 2 | 46458.0691 | 000 | 0 | År Månad Dag |
| 2008 | 2 | 1 | 3108771.9729 | 000 | 0 | År Månad Dag |
| 2008 | 2 | 2 | 54598.5488 | 000 | 0 | År Månad Dag |
| 2007 | 1 | NULL |
1519224.956 | 100 | 1 | Årsmånaden |
| 2007 | 2 | NULL |
2727337.9981 | 100 | 1 | Årsmånaden |
| 2008 | 1 | NULL |
1954580.1658 | 100 | 1 | Årsmånaden |
| 2008 | 2 | NULL |
3163370.5217 | 100 | 1 | Årsmånaden |
| 2007 | NULL |
1 | 4203106.1979 | 010 | 2 | Årets dag |
| 2007 | NULL |
2 | 43456.7562 | 010 | 2 | Årets dag |
| 2008 | NULL |
1 | 5016894.0696 | 010 | 2 | Årets dag |
| 2008 | NULL |
2 | 101056.6179 | 010 | 2 | Årets dag |
| 2007 | NULL |
NULL |
4246562.9541 | 110 | 3 | År |
| 2008 | NULL |
NULL |
5117950.6875 | 110 | 3 | År |
NULL |
1 | 1 | 3405574.7033 | 001 | 4 | Månadsdagen |
NULL |
1 | 2 | 68230.4185 | 001 | 4 | Månadsdagen |
NULL |
2 | 1 | 5814425.5642 | 001 | 4 | Månadsdagen |
NULL |
2 | 2 | 76282.9556 | 001 | 4 | Månadsdagen |
NULL |
1 | NULL |
3473805.1218 | 101 | 5 | Månad |
NULL |
2 | NULL |
5890708.5198 | 101 | 5 | Månad |
NULL |
NULL |
1 | 9220000.2675 | 011 | 6 | Day |
NULL |
NULL |
2 | 144513.3741 | 011 | 6 | Day |
NULL |
NULL |
NULL |
9364513.6416 | 111 | 7 | Totalsumma |