🧚 Dengar! Beekeeper Studio adalah GUI database yang cepat, modern, dan open source Unduh
8 Januari 2026 Oleh Matthew Rathbone

GROUP BY mengumpulkan baris yang memiliki nilai sama ke dalam grup, sehingga fungsi agregat seperti COUNT, SUM, dan AVG mengembalikan satu hasil per grup, bukan satu hasil untuk seluruh tabel. Contoh-contohnya berjalan di PostgreSQL, MySQL, SQLite, dan SQL Server.

Cara menggunakan GROUP BY

Tulis kolom yang ingin dikelompokkan setelah GROUP BY, lalu bungkus setiap kolom lain yang Anda pilih dengan fungsi agregat: COUNT, SUM, AVG, MIN, atau MAX. Anda akan mendapatkan satu baris untuk setiap nilai yang berbeda:

SELECT group_column, AGGREGATE(value_column)
FROM table_name
GROUP BY group_column;
-- Input: scores
-- player | team | points
-- -------+------+-------
-- Ana    | Red  | 12
-- Ben    | Blue | 9
-- Cleo   | Red  | 7
-- Dev    | Blue | 15
-- Eli    | Red  | 4

SELECT team, SUM(points) AS total_points, COUNT(*) AS players
FROM scores
GROUP BY team;

-- Output:
-- team | total_points | players
-- -----+--------------+--------
-- Red  | 23           | 3
-- Blue | 24           | 2

Lima baris menjadi dua, satu per tim, dan setiap agregat hanya melihat baris milik tim tersebut.

Aturan yang perlu diketahui

  • Setiap kolom yang dipilih harus ada di GROUP BY atau di dalam agregat. Jika tidak, tidak ada satu nilai pun yang bisa ditampilkan untuk grup tersebut, dan query akan gagal:
-- Input: products
-- name    | category
-- --------+---------
-- Blender | Kitchen
-- Toaster | Kitchen
-- Pillow  | Bedroom

SELECT name, category, COUNT(*) AS product_count
FROM products
GROUP BY category;

-- ERROR: column "products.name" must appear in the GROUP BY clause
--   or be used in an aggregate function
-- (SQLite runs it anyway and takes name from one row in each group)

Perbaiki dengan menambahkan kolom itu ke GROUP BY, atau dengan mengagregasikannya juga, misalnya dengan MIN(name).

  • NULL membentuk satu grup. Setiap baris dengan NULL di kolom pengelompokan masuk ke grup yang sama. Gunakan COALESCE untuk memberinya label:
-- Input: products
-- name        | category
-- ------------+-----------
-- Notebook    | Stationery
-- Gift Card   | NULL
-- Pen Set     | Stationery
-- Mystery Box | NULL
-- Stapler     | Stationery

SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category;

-- Output:
-- category   | product_count
-- -----------+--------------
-- NULL       | 2
-- Stationery | 3

SELECT COALESCE(category, 'Uncategorized') AS category, COUNT(*) AS product_count
FROM products
GROUP BY category;

-- Output:
-- category      | product_count
-- --------------+--------------
-- Uncategorized | 2
-- Stationery    | 3
  • WHERE memfilter baris sebelum pengelompokan, HAVING memfilter grup sesudahnya. Hanya HAVING yang bisa menguji agregat seperti COUNT(*) > 2. Apa pun yang tidak membutuhkan agregat sebaiknya ditaruh di WHERE, agar lebih sedikit baris yang dikelompokkan.
  • Grup dikembalikan tanpa urutan tertentu. SQLite dan SQL Server, misalnya, menampilkan Blue sebelum Red untuk query skor di atas. Tambahkan ORDER BY setiap kali urutan itu penting.

Sintaks alternatif

Anda bisa mengelompokkan berdasarkan alias kolom, atau berdasarkan posisi kolom di daftar SELECT, tanpa perlu mengulang ekspresi:

-- Input: orders
-- order_id | amount
-- ---------+-------
-- 1        | 35.00
-- 2        | 240.00
-- 3        | 18.50
-- 4        | 120.00
-- 5        | 64.00

SELECT CASE WHEN amount >= 100 THEN 'large' ELSE 'small' END AS order_size,
       COUNT(*) AS order_count
FROM orders
GROUP BY order_size  -- or GROUP BY 1
ORDER BY order_size;
-- SQL Server allows neither: repeat the CASE expression in GROUP BY

-- Output:
-- order_size | order_count
-- -----------+------------
-- large      | 2
-- small      | 3

ROLLUP menambahkan subtotal dan total keseluruhan. Baris subtotal menampilkan NULL di kolom yang dijumlahkannya:

-- Input: sales
-- region | category | amount
-- -------+----------+-------
-- East   | Books    | 100.00
-- East   | Toys     | 50.00
-- West   | Books    | 80.00
-- East   | Books    | 40.00

SELECT region, category, SUM(amount) AS total_sales
FROM sales
GROUP BY ROLLUP(region, category);
-- MySQL: GROUP BY region, category WITH ROLLUP
-- SQLite has no ROLLUP

-- Output:
-- region | category | total_sales
-- -------+----------+------------
-- East   | Books    | 140.00
-- East   | Toys     | 50.00
-- East   | NULL     | 190.00
-- West   | Books    | 80.00
-- West   | NULL     | 80.00
-- NULL   | NULL     | 270.00

GROUP BY tanpa agregat mengembalikan setiap nilai berbeda sekali saja, sama seperti SELECT DISTINCT category FROM products.

Kapan sebaiknya menggunakan GROUP BY?

Gunakan GROUP BY setiap kali pertanyaannya mengandung “per” atau “untuk setiap”: pesanan per pelanggan, penjualan per bulan, karyawan per departemen. Sebagian besar penggunaannya masuk ke salah satu dari empat kategori ini.

Menghitung baris di setiap grup

Berapa banyak pesanan untuk setiap status, berapa produk di setiap kategori, berapa orang yang mendaftar setiap hari. COUNT(*) menghitung setiap baris di grup, sedangkan COUNT(column) hanya menghitung baris yang kolomnya tidak NULL.

Total, rata-rata, atau rentang untuk setiap grup

SUM, AVG, MIN, dan MAX mengubah nilai-nilai di setiap grup menjadi satu angka: pendapatan per pelanggan, rata-rata nilai pesanan, produk termurah dan termahal di suatu kategori. Satu query bisa mengembalikan sebanyak yang Anda butuhkan.

Merinci hasil berdasarkan lebih dari satu kolom

Cantumkan beberapa kolom setelah GROUP BY untuk mendapatkan satu baris per kombinasi: penjualan per wilayah per bulan, stok per gudang per jenis produk. Hanya kombinasi yang ada di data yang akan muncul.

Hanya menyimpan grup yang penting

HAVING memfilter grup setelah terbentuk, menggunakan agregatnya: departemen dengan lebih dari sepuluh orang, pelanggan yang berbelanja lebih dari $1,000, atau nilai yang muncul lebih dari sekali, yang merupakan cara untuk menemukan duplikat.

Contoh nyata GROUP BY

Menghitung produk di setiap kategori, termasuk yang kosong

GROUP BY hanya membuat grup untuk nilai yang ada. Untuk menampilkan juga kategori tanpa produk, mulailah dari tabel categories lalu LEFT JOIN tabel products. Hitung kolom dari tabel yang di-join, bukan *: kategori kosong tetap mendapat satu baris yang diisi NULL, dan COUNT(*) akan ikut menghitungnya.

-- Input: categories
-- category_name
-- -------------
-- Audio
-- Cameras
-- Drones

-- Input: products
-- id | name       | category
-- ---+------------+---------
-- 1  | Earbuds    | Audio
-- 2  | Soundbar   | Audio
-- 3  | Action Cam | Cameras

-- Wrong: COUNT(*) counts the NULL row of an empty category
SELECT c.category_name, COUNT(*) AS product_count
FROM categories c
LEFT JOIN products p ON p.category = c.category_name
GROUP BY c.category_name
ORDER BY c.category_name;

-- Output:
-- category_name | product_count
-- --------------+--------------
-- Audio         | 2
-- Cameras       | 1
-- Drones        | 1

-- Right: COUNT(p.id) skips it
SELECT c.category_name, COUNT(p.id) AS product_count
FROM categories c
LEFT JOIN products p ON p.category = c.category_name
GROUP BY c.category_name
ORDER BY c.category_name;

-- Output:
-- category_name | product_count
-- --------------+--------------
-- Audio         | 2
-- Cameras       | 1
-- Drones        | 0

Menemukan tiga kategori teratas berdasarkan pendapatan

Jumlahkan penjualan setiap kategori, urutkan berdasarkan total, lalu ambil tiga teratas. Books berada di posisi kedua meskipun setiap penjualannya lebih kecil daripada satu-satunya penjualan Toys:

-- Input: purchases
-- category | amount
-- ---------+-------
-- Books    | 45.00
-- Toys     | 120.00
-- Garden   | 310.00
-- Books    | 80.00
-- Music    | 25.00

SELECT category, SUM(amount) AS revenue
FROM purchases
GROUP BY category
ORDER BY revenue DESC
LIMIT 3;
-- SQL Server has no LIMIT: write SELECT TOP 3 category, ... instead

-- Output:
-- category | revenue
-- ---------+--------
-- Garden   | 310.00
-- Books    | 125.00
-- Toys     | 120.00

Laporan penjualan per wilayah per bulan

Kelompokkan berdasarkan wilayah dan bulan yang diambil dari tanggal, sehingga setiap wilayah mendapat satu baris per bulan:

-- Input: sales
-- region | sale_date  | amount
-- -------+------------+-------
-- East   | 2024-01-08 | 120.00
-- West   | 2024-01-15 | 80.00
-- East   | 2024-01-22 | 95.00
-- East   | 2024-02-03 | 60.00
-- West   | 2024-02-11 | 150.00

SELECT region, EXTRACT(MONTH FROM sale_date) AS month, SUM(amount) AS total_sales
FROM sales
GROUP BY region, EXTRACT(MONTH FROM sale_date)
ORDER BY region, month;

-- Output:
-- region | month | total_sales
-- -------+-------+------------
-- East   | 1     | 215.00
-- East   | 2     | 60.00
-- West   | 1     | 80.00
-- West   | 2     | 150.00

SQL Server dan SQLite tidak memiliki EXTRACT. Gunakan MONTH(sale_date) di SQL Server dan strftime('%m', sale_date) di SQLite. Kelompokkan juga berdasarkan tahun jika data Anda mencakup lebih dari satu tahun.

Menemukan pelanggan yang kembali tahun ini

WHERE hanya menyimpan pesanan tahun 2024, lalu HAVING menyimpan pelanggan yang memiliki setidaknya dua pesanan tersebut. Pelanggan 202 memiliki total dua pesanan, tetapi hanya satu di 2024, sehingga tidak disertakan:

-- Input: orders
-- order_id | customer_id | order_date
-- ---------+-------------+-----------
-- 1        | 201         | 2023-11-20
-- 2        | 202         | 2023-12-05
-- 3        | 201         | 2024-01-09
-- 4        | 202         | 2024-02-14
-- 5        | 201         | 2024-03-02

SELECT customer_id, COUNT(*) AS orders_2024
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY customer_id
HAVING COUNT(*) >= 2;

-- Output:
-- customer_id | orders_2024
-- ------------+------------
-- 201         | 2

Bacaan lebih lanjut tentang GROUP BY

Di blog ini:

Dokumentasi resmi:

Beekeeper Studio Adalah GUI Database Gratis & Open Source

Tool query & editor SQL terbaik yang pernah saya pakai. Semua yang saya butuhkan untuk mengelola database ada di sini. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio cepat, intuitif, dan mudah digunakan. Beekeeper mendukung banyak sekali database, dan berjalan mulus di Windows, Mac, dan Linux.

Versi Linux Beekeeper punya fitur 100% lengkap, tanpa potong kompas, tanpa kompromi fitur.

Apa Kata Pengguna Tentang Beekeeper Studio

★★★★★
"Beekeeper Studio benar-benar menggantikan alur kerja SQL lama saya. Cepat, intuitif, dan membuat pekerjaan database kembali menyenangkan."
— Alex K., Database Developer
★★★★★
"Saya sudah mencoba banyak GUI database, tetapi Beekeeper punya keseimbangan sempurna antara fitur dan kesederhanaan. Langsung berfungsi."
— Sarah M., Full Stack Engineer

Siap Meningkatkan Alur Kerja SQL Anda?

download Unduh Gratis