Buat dapetin query ini butuh perjalanan yang agak panjang ‘n jelas wasting time menurut gue, soalnya gue dihadapkan buat menyortir data di database MySQL di 1 kolom & tabel yang sama, dan didalamnya terdapat nilai yang mengandung huruf dan angka.
# Pemahaman
Pada dasarnya, sortir data di MySQL cukup dengan statement ORDER BY yang diikuti field apa yang akan di order, lalu tetapkan pengurutan order dari awal ke akhir atau sebaliknya (ASC/DESC), namun setelah gue dihadapkan dengan sebuah kasus ini, nyatanya gak semudah sesuai yang gue bayangin.
# Kasus
Oke, ceritanya gue kepingin order data di tabel theTable yang memiliki field revisi untuk menghasilkan hasil sortir seperti berikut:
1 2 3 4 5 6 7 8 9 10 |
+--------+ | revisi | +--------+ | 2 | | 1 | | 0 | | Z | | Y | | X | +--------+ |
# Analisa Kasus
Sebelum gue kerjain, gue fikir gampang, sangat gampang.. Tapi, inilah hasil analisa gue selama 3 hari buat bisa dapetin nilai diatas:
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> SELECT revisi FROM `theTable` ORDER BY revisi DESC; +--------+ | revisi | +--------+ | Z | | Y | | X | | 2 | | 1 | | 0 | +--------+ 6 rows in set (0.01 sec) |
Gagal..
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> SELECT revisi FROM `theTable` ORDER BY revisi+0 DESC; +--------+ | revisi | +--------+ | 2 | | 1 | | 0 | | Z | | X | | Y | +--------+ 6 rows in set (0.00 sec) |
Gagal…
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> SELECT revisi FROM `theTable` ORDER BY revisi+0 DESC, revisi DESC; +--------+ | revisi | +--------+ | 2 | | 1 | | Z | | Y | | X | | 0 | +--------+ 6 rows in set (0.01 sec) |
Gagal…
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> SELECT revisi FROM `theTable` ORDER BY revisi=0, revisi DESC; +--------+ | revisi | +--------+ | 2 | | 1 | | Z | | Y | | X | | 0 | +--------+ 6 rows in set (0.01 sec) |
Gagal….
# Solusi
Alhasil di hari ketiga, inilah rumusan query yang gue dapet buat dapetin nilai sesuai harapan:
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> SELECT revisi FROM `theTable` ORDER BY CASE WHEN CONCAT('',revisi * 1) = revisi THEN 0 ELSE 1 END, revisi DESC; +--------+ | revisi | +--------+ | 2 | | 1 | | 0 | | Z | | Y | | X | +--------+ 6 rows in set (0.00 sec) |
# Pemahaman
Pada dasarnya yang jadi masalah disini adalah sorting 0 (nol) yang diabaikan oleh MySQL karena 0 bernilai sama dengan NULL.
1 |
SELECT revisi FROM `theTable` ORDER BY CASE WHEN CONCAT('',revisi * 1) = revisi THEN 0 ELSE 1 END, revisi DESC; |
Dengan query solusi diatas, gue menggunakan CONCAT(”,revisi * 1) = revisi untuk mengetahui dan memaksakan nilai 0 sebagai nomor integer, bukan lagi bernilai NULL, yang kemudian diikuti menyortir field revisi DESC untuk menyortir nilai huruf dulu kemudian nomor secara descending.
Semoga membantu 🙂