Aracılığıyla paylaş


GROUPING_ID (Transact-SQL)

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen ÖrneğiMicrosoft Fabric'te SQL veritabanı

GROUPING_ID Gruplama seviyesini hesaplayan bir fonksiyondur. GROUPING_ID yalnızca SELECT <select> listede, HAVING, veya ORDER BY belirtildiğinde cümlelerde GROUP BY kullanılabilir.

Transact-SQL söz dizimi kuralları

Sözdizimi

GROUPING_ID ( <column_expression> [ , ...n ] )

Arguments

<column_expression>

SELECT - GROUP BY cümlesinde bir column_expression.

Dönüş türleri

int

Açıklamalar

Listedeki GROUPING_ID <column_expression>GROUP BY ifadeyle tam olarak eşleşmeli. Örneğin, gruplarsanız DATEPART (yyyy, <column name>), GROUPING_ID (DATEPART (yyyy, <column name>))kullanın; veya gruplarsanız <column name>, GROUPING_ID (<column name>).

GROUPING_ID() ile GRUPLAŞMA() ile karşılaştırın.

GROUPING_ID (<column_expression> [ , ...n ]) her çıktı satırındaki sütun listesindeki her sütunun dönüş değerini GROUPING (<column_expression>) birler ve sıfırlardan oluşan bir dizi olarak girer. GROUPING_ID o diziyi taban-2 olarak yorumlar ve eşdeğer tam sayı döndürür.

Örneğin, aşağıdaki ifadeyi ele alalım:

SELECT a, b, c, SUM(d),
GROUPING_ID(a, b, c)
FROM T
GROUP BY <group_by_list>

Bu tablo giriş ve çıkış değerlerini GROUPING_ID() gösterir.

Sütunların toplanması GROUPING_ID (a, b, c) girdi = GRUPLAŞMA(a) + GRUPLANMA(b) + GRUPLANMA(c) GROUPING_ID() çıkışı
a 100 4
b 010 2
c 001 1
ab 110 6
ac 101 5
bc 011 3
abc 111 7

GROUPING_ID() teknik tanımı

Her GROUPING_ID argüman listenin GROUP BY bir unsuru olmalıdır. GROUPING_ID() en düşük n biti yandırılabilir bir tam sayı bitmap döndürür. Bir lit bit, ilgili argümanın, verilen çıktı satırı için bir gruplama sütunu olmadığını gösterir. En düşük dereceden bit argüman n'ye, n-1'inen düşük dereceli biti ise argüman 1'e karşılık gelir.

GROUPING_ID() karşılığı

Tek bir gruplama sorgusu için, GROUPING (<column_expression>) eşdeğerdir GROUPING_ID (<column_expression>)ve her ikisi de döndürür 0.

Örneğin, aşağıdaki ifadeler eşdeğerdir:

A İfadesi

SELECT GROUPING_ID(A, B)
FROM T
GROUP BY CUBE(A, B)

B İfadesi

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

Örnekler

Bu makaledeki kod örnekleri, AdventureWorks2025 giriş sayfasından indirebileceğiniz AdventureWorksDW2025 veya örnek veritabanını kullanır.

A. Gruplama seviyelerini belirlemek için GROUPING_ID kullanın

Aşağıdaki örnek, veri tabanında çalışan sayısını ve Nameşirket toplamını Title döndürürAdventureWorks2025. GROUPING_ID() sütundaki her satır Title için bir değer oluşturmak için kullanılır ve bu değer toplama seviyesini gösterir.

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. Sonuç kümesini filtrelemek için GROUPING_ID kullanın

Temel örnek

Aşağıdaki kodda, yalnızca başlığa göre çalışan sayısı olan satırlar döndürülmek için, yorum karakterlerini kaldırın HAVING GROUPING_ID(D.Name, E.JobTitle) = 0;. Sadece departmanlara göre çalışan sayısının olduğu satırlar döndürmek için, yorum karakterlerini kaldırı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;

İşte filtrelenmemiş sonuç seti.

İsim Başlık Gruplama Seviyesi Çalışan Sayısı İsim
Belge Kontrolü Kontrol Uzmanı 0 2 Belge Kontrolü
Belge Kontrolü Belge Kontrol Asistanı 0 2 Belge Kontrolü
Belge Kontrolü Belge Kontrol Yöneticisi 0 1 Belge Kontrolü
Belge Kontrolü NULL 1 5 Belge Kontrolü
Tesisler ve Bakım Tesisler İdari Asistanı 0 1 Tesisler ve Bakım
Tesisler ve Bakım Tesis Müdürü 0 1 Tesisler ve Bakım
Tesisler ve Bakım Hademe 0 4 Tesisler ve Bakım
Tesisler ve Bakım Bakım Süpervizörü 0 1 Tesisler ve Bakım
Tesisler ve Bakım NULL 1 7 Tesisler ve Bakım
NULL NULL 3 12 NULL

Karmaşık örnek

Aşağıdaki örnek, birden fazla gruplama seviyesi içeren bir sonuç kümesini gruplama seviyesine göre filtrelemek için kullanılır GROUPING_ID() . Benzer kod, birkaç gruplama seviyesine sahip bir görünüm oluşturmak ve görünümü gruplama seviyesine göre filtreleyen bir parametre ileten bir kayıtlı prosedür oluşturmak için kullanılabilir.

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. Gruplama seviyelerini belirlemek için GROUPING_ID() ile ROLLUP ve CUBE kullanın

Aşağıdaki örneklerdeki kod, sütunu GROUPING() hesaplamak için kullandığınızı Bit Vector(base-2) gösterir. GROUPING_ID() karşılık gelen sütunu hesaplamak Integer Equivalent için kullanılır. Fonksiyondaki GROUPING_ID() sütun sırası, fonksiyon tarafından birleştirilen GROUPING() sütunların sütun sırasının tam tersidir.

Bu örneklerde, GROUPING_ID() sütundaki her satır Grouping Level için bir değer oluşturmak ve gruplama seviyesini belirlemek için kullanılır. Gruplama seviyeleri her zaman 1 (0, 1, 2, ... n).

Uyarı

GROUPING ve GROUPING_ID bir HAVING cümlede bir sonuç kümesini filtrelemek için kullanılabilir.

ROLLUP örneği

Bu örnekte, tüm gruplama seviyeleri aşağıdaki CUBE örnekte olduğu gibi görünmez. Listedeki ROLLUP sütunların sırası değiştirilirse, sütundaki seviye değerleri Grouping Level de değiştirilmelidir.

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);

Kısmi bir sonuç kümesi aşağıdadır.

Yıl Ay Day Toplam Son Tarih Bit Vektörü (baz-2) Tamsayı Eşdeğeri Gruplama Seviyesi
2007 1 1 1497452.6066 000 0 Yıl Ay Günü
2007 1 2 21772.3494 000 0 Yıl Ay Günü
2007 2 1 2705653.5913 000 0 Yıl Ay Günü
2007 2 2 21684.4068 000 0 Yıl Ay Günü
2008 1 1 1908122.0967 000 0 Yıl Ay Günü
2008 1 2 46458.0691 000 0 Yıl Ay Günü
2008 2 1 3108771.9729 000 0 Yıl Ay Günü
2008 2 2 54598.5488 000 0 Yıl Ay Günü
2007 1 NULL 1519224.956 100 1 Yıl Ayı
2007 2 NULL 2727337.9981 100 1 Yıl Ayı
2008 1 NULL 1954580.1658 100 1 Yıl Ayı
2008 2 NULL 3163370.5217 100 1 Yıl Ayı
2007 NULL NULL 4246562.9541 110 3 Yıl
2008 NULL NULL 5117950.6875 110 3 Yıl
NULL NULL NULL 9364513.6416 111 7 Genel Toplam

CUBE örneği

Bu örnekte, GROUPING_ID() fonksiyon sütundaki her satır Grouping Level için bir değer oluşturmak ve gruplama seviyesini tanımlamak için kullanılır.

Önceki örnekten farklı ROLLUP olarak, CUBE tüm gruplama seviyeleri çıkar. Listedeki CUBE sütunların sırası değiştirilirse, sütundaki seviye değerleri Grouping Level de değiştirilmelidir.

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);

Kısmi bir sonuç kümesi aşağıdadır.

Yıl Ay Day Toplam Son Tarih Bit Vektörü (baz-2) Tamsayı Eşdeğeri Gruplama Seviyesi
2007 1 1 1497452.6066 000 0 Yıl Ay Günü
2007 1 2 21772.3494 000 0 Yıl Ay Günü
2007 2 1 2705653.5913 000 0 Yıl Ay Günü
2007 2 2 21684.4068 000 0 Yıl Ay Günü
2008 1 1 1908122.0967 000 0 Yıl Ay Günü
2008 1 2 46458.0691 000 0 Yıl Ay Günü
2008 2 1 3108771.9729 000 0 Yıl Ay Günü
2008 2 2 54598.5488 000 0 Yıl Ay Günü
2007 1 NULL 1519224.956 100 1 Yıl Ayı
2007 2 NULL 2727337.9981 100 1 Yıl Ayı
2008 1 NULL 1954580.1658 100 1 Yıl Ayı
2008 2 NULL 3163370.5217 100 1 Yıl Ayı
2007 NULL 1 4203106.1979 010 2 Yıl Günü
2007 NULL 2 43456.7562 010 2 Yıl Günü
2008 NULL 1 5016894.0696 010 2 Yıl Günü
2008 NULL 2 101056.6179 010 2 Yıl Günü
2007 NULL NULL 4246562.9541 110 3 Yıl
2008 NULL NULL 5117950.6875 110 3 Yıl
NULL 1 1 3405574.7033 001 4 Ay Günü
NULL 1 2 68230.4185 001 4 Ay Günü
NULL 2 1 5814425.5642 001 4 Ay Günü
NULL 2 2 76282.9556 001 4 Ay Günü
NULL 1 NULL 3473805.1218 101 5 Ay
NULL 2 NULL 5890708.5198 101 5 Ay
NULL NULL 1 9220000.2675 011 6 Day
NULL NULL 2 144513.3741 011 6 Day
NULL NULL NULL 9364513.6416 111 7 Genel Toplam