Fungsi RANK, DENSE_RANK dan ROW_NUMBER digunakan untuk mengambil nilai integer yang meningkat. Mereka mulai dengan nilai berdasarkan kondisi yang diberlakukan oleh klausa ORDER BY. Semua fungsi ini membutuhkan klausa ORDER BY untuk berfungsi dengan baik. Dalam kasus data yang dipartisi, penghitung bilangan bulat direset ke 1 untuk setiap partisi.
Dalam artikel ini, kita akan mempelajari fungsi RANK, DENSE_RANK dan ROW_NUMBER secara mendetail, tetapi sebelum itu, mari kita buat data dummy tempat fungsi-fungsi ini dapat digunakan kecuali database Anda dicadangkan sepenuhnya.
Menyiapkan Data Dummy
Jalankan skrip berikut untuk membuat database bernama ShowRoom dan berisi tabel bernama Cars (yang berisi 15 record acak mobil):
CREATE Database ShowRoom; GO USE ShowRoom; CREATE TABLE Cars ( id INT, name VARCHAR(50) NOT NULL, company VARCHAR(50) NOT NULL, power INT NOT NULL ) USE ShowRoom INSERT INTO Cars VALUES (1, 'Corrolla', 'Toyota', 1800), (2, 'City', 'Honda', 1500), (3, 'C200', 'Mercedez', 2000), (4, 'Vitz', 'Toyota', 1300), (5, 'Baleno', 'Suzuki', 1500), (6, 'C500', 'Mercedez', 5000), (7, '800', 'BMW', 8000), (8, 'Mustang', 'Ford', 5000), (9, '208', 'Peugeot', 5400), (10, 'Prius', 'Toyota', 3200), (11, 'Atlas', 'Volkswagen', 5000), (12, '110', 'Bugatti', 8000), (13, 'Landcruiser', 'Toyota', 3000), (14, 'Civic', 'Honda', 1800), (15, 'Accord', 'Honda', 2000)
Fungsi PERINGKAT
Fungsi RANK digunakan untuk mengambil baris berperingkat berdasarkan kondisi klausa ORDER BY. Misalnya, jika Anda ingin mencari nama mobil dengan kekuatan tertinggi ketiga, Anda dapat menggunakan Fungsi RANK.
Mari kita lihat Fungsi RANK beraksi:
SELECT name,company, power, RANK() OVER(ORDER BY power DESC) AS PowerRank FROM Cars
Script di atas menemukan dan memberi peringkat pada semua record di tabel Cars dan mengurutkannya dalam urutan kekuatan menurun. Outputnya terlihat seperti ini:
Kolom PowerRank pada tabel di atas berisi RANK mobil yang diurutkan berdasarkan kekuatannya. Hal yang menarik dari fungsi RANK adalah jika ada ikatan antara N record sebelumnya untuk nilai pada kolom ORDER BY, fungsi RANK akan melompati posisi N-1 berikutnya sebelum menambah counter. Misalnya, pada hasil di atas, ada ikatan untuk nilai pada kolom pangkat antara baris ke-1 dan ke-2, oleh karena itu fungsi RANK melewatkan satu record berikutnya (2-1 =1) dan melompat langsung ke baris ke-3.
Fungsi RANK dapat digunakan dalam kombinasi dengan klausa PARTITION BY. Dalam hal ini, peringkat akan diatur ulang untuk setiap partisi baru. Perhatikan script berikut:
SELECT name,company, power, RANK() OVER(PARTITION BY company ORDER BY power DESC) AS PowerRank FROM Cars
Dalam skrip di atas, kami mempartisi hasil berdasarkan kolom perusahaan. Sekarang untuk setiap perusahaan, RANK akan direset menjadi 1 seperti yang ditunjukkan di bawah ini:
Fungsi DENSE_RANK
Fungsi DENSE_RANK mirip dengan fungsi RANK namun fungsi DENSE_RANK tidak melewatkan peringkat apa pun jika ada ikatan antara peringkat catatan sebelumnya. Perhatikan script berikut.
SELECT name,company, power, RANK() OVER(PARTITION BY company ORDER BY power DESC) AS PowerRank FROM Cars
Anda dapat melihat dari output bahwa meskipun ada ikatan antara peringkat dari dua baris pertama, peringkat berikutnya tidak dilewati dan telah diberi nilai 2, bukan 3. Seperti fungsi RANK, klausa PARTITION BY dapat juga dapat digunakan dengan fungsi DENSE_RANK seperti yang ditunjukkan di bawah ini:
SELECT name,company, power, DENSE_RANK() OVER(PARTITION BY company ORDER BY power DESC) AS DensePowerRank FROM Cars
Fungsi ROW_NUMBER
Berbeda dengan fungsi RANK dan DENSE_RANK, fungsi ROW_NUMBER hanya mengembalikan nomor baris dari record yang diurutkan yang dimulai dengan 1. Misalnya, jika fungsi RANK dan DENSE_RANK dari dua record pertama di kolom ORDER BY adalah sama, keduanya diberi nilai 1 sebagai RANK dan DENSE_RANK mereka. Namun, fungsi ROW_NUMBER akan menetapkan nilai 1 dan 2 ke baris tersebut tanpa memperhitungkan fakta bahwa keduanya sama-sama diperhitungkan. Jalankan skrip berikut untuk melihat fungsi ROW_NUMBER beraksi.
SELECT name,company, power, ROW_NUMBER() OVER(ORDER BY power DESC) AS RowRank FROM Cars
Dari output, Anda dapat melihat bahwa fungsi ROW_NUMBER hanya menetapkan nomor baris baru untuk setiap record terlepas dari nilainya.
Klausa PARTITION BY juga dapat digunakan dengan fungsi ROW_NUMBER seperti yang ditunjukkan di bawah ini:
SELECT name, company, power, ROW_NUMBER() OVER(PARTITION BY company ORDER BY power DESC) AS RowRank FROM Cars
Outputnya terlihat seperti ini:
Kesamaan antara Fungsi RANK, DENSE_RANK, dan ROW_NUMBER
Fungsi RANK, DENSE_RANK dan ROW_NUMBER memiliki kesamaan sebagai berikut:
1- Semuanya membutuhkan urutan dengan klausa.
2- Semuanya mengembalikan bilangan bulat yang meningkat dengan nilai dasar 1.
3- Ketika digabungkan dengan klausa PARTITION BY, semua fungsi ini mereset nilai integer yang dikembalikan ke 1 seperti yang telah kita lihat.
4- Jika tidak ada nilai duplikat di kolom yang digunakan oleh klausa ORDER BY, ini fungsi mengembalikan output yang sama.
Untuk mengilustrasikan poin terakhir, mari buat tabel baru Car1 di database ShowRoom tanpa nilai duplikat di kolom daya. Jalankan script berikut:
USE ShowRoom; CREATE TABLE Cars1 ( id INT, name VARCHAR(50) NOT NULL, company VARCHAR(50) NOT NULL, power INT NOT NULL ) INSERT INTO Cars1 VALUES (1, 'Corrolla', 'Toyota', 1800), (2, 'City', 'Honda', 1500), (3, 'C200', 'Mercedez', 2000), (4, 'Vitz', 'Toyota', 1300), (5, 'Baleno', 'Suzuki', 2500), (6, 'C500', 'Mercedez', 5000), (7, '800', 'BMW', 8000), (8, 'Mustang', 'Ford', 4000), (9, '208', 'Peugeot', 5400), (10, 'Prius', 'Toyota', 3200) The cars1 table has no duplicate values. Now let’s execute the RANK, DENSE_RANK and ROW_NUMBER functions on the Cars1 table ORDER BY power column. Execute the following script: SELECT name,company, power, RANK() OVER(ORDER BY power DESC) AS [Rank], DENSE_RANK() OVER(ORDER BY power DESC) AS [Dense Rank], ROW_NUMBER() OVER(ORDER BY power DESC) AS [Row Number] FROM Cars1
Outputnya terlihat seperti ini:
Anda dapat melihat bahwa tidak ada nilai duplikat di kolom daya yang digunakan dalam klausa ORDER BY, oleh karena itu output dari fungsi RANK, DENSE_RANK, dan ROW_NUMBER adalah sama.
Perbedaan antara Fungsi RANK, DENSE_RANK dan ROW_NUMBER
Satu-satunya perbedaan antara fungsi RANK, DENSE_RANK dan ROW_NUMBER adalah ketika ada nilai duplikat di kolom yang digunakan dalam ORDER BY Clause.
Jika Anda kembali ke tabel Mobil di database ShowRoom, Anda dapat melihatnya berisi banyak nilai duplikat. Mari kita coba mencari RANK, DENSE_RANK, dan ROW_NUMBER dari tabel Cars1 yang diurutkan berdasarkan daya. Jalankan skrip berikut:
SELECT name,company, power,
RANK() OVER(ORDER BY power DESC) AS [Rank], DENSE_RANK() OVER(ORDER BY power DESC) AS [Dense Rank], ROW_NUMBER() OVER(ORDER BY power DESC) AS [Row Number] FROM Cars
Outputnya terlihat seperti ini:
Dari output tersebut, Anda dapat melihat bahwa fungsi RANK melompati peringkat N-1 berikutnya jika ada seri antara N peringkat sebelumnya. Di sisi lain, fungsi DENSE_RANK tidak melewatkan peringkat jika ada ikatan antar peringkat. Terakhir, fungsi ROW_NUMBER tidak peduli dengan peringkat. Ini hanya mengembalikan nomor baris dari catatan yang diurutkan. Bahkan jika ada catatan duplikat di kolom yang digunakan dalam klausa ORDER BY, fungsi ROW_NUMBER tidak akan mengembalikan nilai duplikat. Sebaliknya, itu akan terus bertambah terlepas dari nilai duplikatnya.
Tautan yang berguna:
Untuk mempelajari lebih lanjut tentang fungsi ROW_NUMBER(), RANK() dan DENSE_RANK(), baca artikel fantastis oleh Ahmad Yaseen:
Metode untuk Memberi Peringkat Baris di SQL Server:ROW_NUMBER(), RANK(), DENSE_RANK() dan NTILE()