GROUP BY ile verileri özetleme

Tamamlandı

Toplama işlevleri analiz için yararlı olsa da, özetlemeden önce verilerinizi alt kümeler halinde düzenlemek isteyebilirsiniz. Bu bölümde GROUP BY yan tümcesini kullanarak bunu nasıl gerçekleştireceğinizi öğreneceksiniz.

GROUP BY yan tümcesini kullanma

Öğrendiğiniz gibi, SELECT deyiminiz işlendiğinde FROM yan tümcesi ve WHERE yan tümcesi değerlendirildikten sonra bir sanal tablo oluşturulur. Sanal tablonun içeriği artık daha fazla işlem için kullanılabilir. Bu sanal tablonun içeriğini satır gruplarına ayırmak için GROUP BY yan tümcesini kullanabilirsiniz.

Satırları gruplandırmak için GROUP BY yan tümcesinde bir veya daha fazla öğe belirtin:

GROUP BY <value1> [, <value2>, …]

GROUP BY grupları oluşturur ve yan tümcesinde belirtilen öğeler tarafından belirlenen her gruba satır yerleştirir.

Örneğin, aşağıdaki sorgu Sales.SalesOrderHeader tablosunda CustomerID başına bir satır olmak üzere gruplandırılmış bir satır kümesine neden olur. GROUP BY işlemine bakmanın bir diğer yolu da CustomerID için aynı değere sahip tüm satırların birlikte gruplanması ve tek bir sonuç satırında döndürülmüş olmasıdır.

SELECT CustomerID
FROM Sales.SalesOrderHeader
GROUP BY CustomerID;

Yukarıdaki sorgu aşağıdaki sorguya eşdeğerdir:

SELECT DISTINCT CustomerID
FROM Sales.SalesOrderHeader

GROUP BY yan tümcesi işlendikten ve her satır bir grupla ilişkilendirildikten sonra, sorgunun sonraki aşamaları SELECT listesinde yer alan ancak GROUP BY listesinde görünmeyen kaynak satırların öğelerini toplamalıdır. Bu gereksinim, SELECT ve HAVING yan tümcelerinizi yazma şeklinizi etkiler.

Peki, sorguyu GROUP BY veya DISTINCT ile yazma arasındaki fark nedir? Tek bilmek istediğiniz CustomerID için ayrı değerlerse fark yoktur. Ancak GROUP BY ile SELECT listesine daha sonra her grup için toplanan başka öğeler ekleyebiliriz.

En basit toplama işlevi COUNT(*) işlevidir. Aşağıdaki sorgu CustomerID'den özgün 830 kaynak satırı alır ve Bunları CustomerID değerlerine göre 89 gruba ayırır. Her ayrı CustomerID değeri GROUP BY sorgusunda bir çıkış satırı oluşturur

SELECT CustomerID, COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID;

Her CustomerID değeri için sorgu satırları toplar ve sayar, bu nedenle SalesOrderHeader tablosundaki her müşteriye ait olan satır sayısını gösterir.

CustomerID

OrderCount

1234

3

1005

1

GROUP BY'ın sonuçların sırasını garanti etmediğini unutmayın. Genellikle, gruplandırma işleminin sorgu işlemcisi tarafından gerçekleştiriliş şeklinin bir sonucu olarak, sonuçlar grup değerlerinin sırasına göre döndürülür. Ancak, bu davranışa güvenmemelisiniz. Sonuçların sıralanması gerekiyorsa, order yan tümcesini açıkça eklemeniz gerekir:

SELECT CustomerID, COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID
ORDER BY CustomerID;

Bu kez sonuçlar belirtilen sırada döndürülür:

CustomerID

OrderCount

1005

1

1234

3

SELECT deyimindeki yan tümceler aşağıdaki sırayla uygulanır:

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY

Sütun diğer adları, GROUP BY yan tümcesinin ardından ancak ORDER BY yan tümcesi öncesinde gerçekleşen SELECT yan tümcesinde atanır. ORDER BY yan tümcesinde bir sütun diğer adına başvurabilirsiniz, ancak GROUP BY yan tümcesinde başvuramayın. Aşağıdaki sorgu geçersiz bir sütun adı hatasına neden olur:

SELECT CustomerID AS Customer,
       COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY Customer
ORDER BY Customer;

Ancak aşağıdaki sorgu başarılı olur ve sonuçları müşteri kimliğine göre gruplandırıp sıralar.

SELECT CustomerID AS Customer,
       COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID
ORDER BY Customer;

GROUP BY hatalarını giderme

SELECT deyimlerinde GROUP BY kullanmanın rahat olmasının yaygın bir engeli, aşağıdaki tür hata iletisinin neden oluştuğunun anlaşılmasıdır:

Msg 8120, Düzey 16, Durum 1, Satır 2 Sütun <column_name> , toplama işlevinde veya GROUP BY yan tümcesinde yer almadığından seçme listesinde geçersizdir.

Örneğin, SELECT listesindeki her sütun GROUP BY yan tümcesindeki bir sütun veya her grupta çalışan bir toplama işlevi olduğundan aşağıdaki sorguya izin verilir:

SELECT CustomerID, COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID;

PurchaseOrderNumber GROUP BY'ın bir parçası olmadığından ve bir toplama işleviyle kullanılmadığından aşağıdaki sorgu bir hata döndürür.

SELECT CustomerID, PurchaseOrderNumber, COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID;

Bu sorgu şu hatayı döndürür:

Msg 8120, Level 16, State 1, Line 1
Column 'Sales.SalesOrderHeader.PurchaseOrderNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Bunu düşünmenin başka bir yolu daha var. Bu sorgu, her CustomerID değeri için bir satır döndürür. Ancak aynı CustomerID'nin satırları farklı PurchaseOrderNumber değerlerine sahip olabilir, dolayısıyla döndürülmesi gereken değerlerden hangisidir?

Müşteri kimliği ve satınalma siparişi başına siparişleri görmek istiyorsanız, Group BY yan tümcesine PurchaseOrderNumber sütununu aşağıdaki gibi ekleyebilirsiniz:

SELECT CustomerID, PurchaseOrderNumber, COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY CustomerID, PurchaseOrderNumber;

Bu sorgu, her müşteri ve her satınalma siparişi birleşimi için bir satır ve bu birleşimin sipariş sayısını döndürür.