Berikut adalah lima opsi untuk menggunakan SQL untuk mengembalikan hanya baris yang memiliki nilai minimum dalam grupnya.
Contoh-contoh ini berfungsi di sebagian besar RDBMS utama, termasuk MySQL, MariaDB, Oracle, PostgreSQL, SQLite, dan SQL Server.
Contoh Data
Misalkan kita memiliki tabel dengan data berikut:
SELECT * FROM Gameshow;
Hasil:
+--------------+--------+---------+ | Contestant | Game | Score | |--------------+--------+---------| | Faye | 1 | 85 | | Faye | 2 | 50 | | Faye | 3 | 63 | | Jet | 1 | 31 | | Jet | 2 | 40 | | Jet | 3 | 51 | | Spike | 1 | 25 | | Spike | 2 | 27 | | Spike | 3 | 15 | +--------------+--------+---------+
Dan misalkan kita ingin mendapatkan nilai terendah untuk setiap kontestan.
Opsi 1
Opsi cepat dan mudah adalah membuat kueri dengan SQL GROUP BY
klausa:
SELECT
Contestant,
MIN( Score ) AS MinScore
FROM Gameshow
GROUP BY Contestant
ORDER BY Contestant;
Hasil:
+--------------+------------+ | Contestant | MinScore | |--------------+------------| | Faye | 50 | | Jet | 31 | | Spike | 15 | +--------------+------------+
Opsi 2
Jika kita ingin memasukkan game yang dimainkan setiap kontestan untuk mendapatkan skor minimum, maka salah satu caranya adalah dengan menggunakan subquery berkorelasi seperti ini:
SELECT
Contestant,
Game,
Score
FROM Gameshow g1
WHERE Score = ( SELECT MIN( g2.Score )
FROM Gameshow g2
WHERE g1.Contestant = g2.Contestant )
ORDER BY Contestant;
Hasil:
+--------------+--------+---------+ | Contestant | Game | Score | |--------------+--------+---------| | Faye | 2 | 50 | | Jet | 1 | 31 | | Spike | 3 | 15 | +--------------+--------+---------+
Subquery berkorelasi mengacu pada satu atau lebih kolom dari luar subquery. Subquery yang berkorelasi dapat menjadi tidak efisien, terutama karena fakta bahwa subquery dieksekusi berulang kali, sekali untuk setiap baris yang mungkin dipilih oleh kueri luar. Subquery berkorelasi juga dikenal sebagai subquery berulang.
Opsi 3
Sebagai alternatif, kita dapat menggunakan subquery yang tidak berkorelasi seperti ini:
SELECT
g1.Contestant,
g1.Game,
g1.Score
FROM Gameshow g1
JOIN (
SELECT Contestant, MIN( Score ) AS Score
FROM Gameshow
GROUP BY Contestant ) AS g2
ON g1.Contestant = g2.Contestant AND g1.Score = g2.Score
ORDER BY Contestant ASC;
Hasil:
+--------------+--------+---------+ | Contestant | Game | Score | |--------------+--------+---------| | Faye | 2 | 50 | | Jet | 1 | 31 | | Spike | 3 | 15 | +--------------+--------+---------+
Subkueri yang tidak berkorelasi tidak bergantung pada kueri luar untuk eksekusinya. Mereka dapat mengeksekusi sepenuhnya secara independen dari kueri luar.
Di Oracle, kita perlu menghapus AS
saat mendeklarasikan alias kolom:
SELECT
g1.Contestant,
g1.Game,
g1.Score
FROM Gameshow g1
JOIN (
SELECT Contestant, MIN( Score ) Score
FROM Gameshow
GROUP BY Contestant ) g2
ON g1.Contestant = g2.Contestant AND g1.Score = g2.Score
ORDER BY Contestant ASC;
Opsi 4
Cara lain untuk mengambil baris dengan nilai minimum dalam kolom tertentu adalah dengan menggunakan LEFT JOIN
, seperti ini:
SELECT
g1.Contestant,
g1.Game,
g1.Score
FROM Gameshow g1
LEFT JOIN Gameshow g2 ON
g1.Contestant = g2.Contestant AND g1.Score > g2.Score
WHERE g2.Contestant IS NULL
ORDER BY g1.Contestant ASC;
Hasil:
+--------------+--------+---------+ | Contestant | Game | Score | |--------------+--------+---------| | Faye | 2 | 50 | | Jet | 1 | 31 | | Spike | 3 | 15 | +--------------+--------+---------+
Opsi 5
Cara lain untuk melakukannya adalah dengan menggunakan ekspresi tabel umum dengan fungsi jendela:
WITH cte AS (
SELECT Contestant, Game, Score,
RANK() OVER ( PARTITION BY Contestant
ORDER BY Score ASC
) AS r
FROM Gameshow
)
SELECT Contestant, Game, Score
FROM cte
WHERE r = 1
ORDER BY Contestant ASC;
Hasil:
+--------------+--------+---------+ | Contestant | Game | Score | |--------------+--------+---------| | Faye | 2 | 50 | | Jet | 1 | 31 | | Spike | 3 | 15 | +--------------+--------+---------+