SQLite Punya Lebih Banyak Fungsi Matematika dari yang Kamu Kira
SQLite terkenal minimalis, tapi SQLite membawa satu set lengkap fungsi numerik: pembulatan, nilai absolut, pembulatan ke atas dan ke bawah, pangkat, akar, logaritma, trigonometri, dan bilangan acak. Sebagian besar fungsi matematika ditambahkan di SQLite 3.35 (2021), jadi instalasi apa pun yang cukup modern, seperti yang dibundel bersama Python, Node, pendahulu WebSQL di browsermu, atau CLI resminya, sudah langsung bisa memakainya.
Ini contoh singkatnya sebelum kita membahas lebih dalam:
Enam fungsi, satu baris hasil. Sisa halaman ini membahas kegunaan setiap kelompok fungsi dan jebakan yang perlu kamu ketahui.
ROUND: Fungsi yang Paling Sering Kamu Pakai
ROUND(value, digits) membulatkan ke sejumlah angka desimal tertentu. Argumen kedua opsional: jika tidak ditulis, kamu mendapat pembulatan ke integer terdekat (tapi tetap dalam bentuk nilai floating-point):
Beberapa hal yang perlu diperhatikan:
ROUND(3.14159)mengembalikan3.0, bukan3. Jika kamu ingin integer, pakaiCAST(ROUND(x) AS INTEGER)atau cukupCAST(x AS INTEGER)untuk memotong.- SQLite memakai aturan "bulatkan setengah menjauhi nol":
2.5dibulatkan menjadi3,-2.5dibulatkan menjadi-3. Beberapa database memakai banker's rounding (bulatkan setengah ke bilangan genap); SQLite tidak. - Argumen
digitsboleh negatif:ROUND(1234.5, -2)membulatkan ke kelipatan 100 terdekat, menghasilkan1200.
Dalam praktiknya, yang paling sering kamu tulis adalah ROUND(price, 2) untuk menampilkan nilai uang.
ROUND vs CAST: Keduanya Berbeda
Orang sering memakai CAST(x AS INTEGER) padahal maksudnya membulatkan, lalu kena batunya:
CAST memotong ke arah nol: bagian pecahannya dibuang begitu saja. ROUND membulatkan ke integer terdekat. Untuk 2.9, selisih keduanya satu angka penuh. Pilih yang perilakunya memang kamu inginkan.
ABS, SIGN, dan Tanda Sebuah Bilangan
ABS(x) mengembalikan nilai absolut. SIGN(x) mengembalikan -1, 0, atau 1 sesuai tanda bilangannya:
ABS adalah andalannya, praktis untuk query "seberapa jauh jarak dua nilai ini". SIGN lebih jarang dipakai, tapi berguna saat kamu ingin mengelompokkan baris berdasarkan arahnya (debit vs kredit, untung vs rugi) tanpa CASE eksplisit.
CEIL, FLOOR, dan TRUNC
Fungsi-fungsi ini memberimu nilai mirip integer tanpa membulatkan ke yang terdekat. CEIL selalu naik, FLOOR selalu turun, TRUNC selalu menuju nol:
Perhatikan kasus negatifnya. FLOOR(-2.9) adalah -3 (lebih jauh dari nol), tapi TRUNC(-2.9) adalah -2 (menuju nol). Untuk bilangan negatif, FLOOR dan TRUNC memberi hasil berbeda, dan salah memilih adalah bug selisih satu yang klasik.
CEILING adalah alias untuk CEIL. Pakai ejaan mana pun yang menurutmu lebih enak dibaca.
Pembagian Integer Adalah Jebakan Sebenarnya
Ini bukan fungsi, melainkan operator /, tapi lebih sering menjebak pemula daripada fungsi matematika mana pun:
Jika kedua sisi integer, SQLite melakukan pembagian integer dan memotong hasilnya. Begitu salah satu sisi bertipe REAL, seluruh ekspresinya menjadi real. Solusinya adalah memastikan setidaknya satu operan berupa float, entah dengan menulis 2.0 alih-alih 2, atau dengan cast.
Jebakan ini paling terasa dengan referensi kolom: total_cents / 100 mengembalikan integer. total_cents / 100.0 mengembalikan nilai dolar yang sebenarnya kamu inginkan.
MOD dan Operator %
MOD(x, y) mengembalikan sisa dari x / y. Operator % melakukan hal yang sama:
MOD(17, 5) dan 17 % 5 sama-sama mengembalikan 2. Modulo dengan nol menghasilkan NULL di SQLite, tanpa memunculkan error, dan ini tidak biasa dibandingkan kebanyakan bahasa. Jika itu penting bagimu, cek pembaginya dulu atau bungkus pemanggilannya dengan CASE WHEN y = 0 THEN ... END.
Bentuk fungsi dan operatornya bisa saling menggantikan. Kebanyakan orang memakai % karena lebih pendek.
POWER, SQRT, EXP, LOG
Untuk pangkat dan akar:
Beberapa catatan yang sering menjebak:
POWadalah alias untukPOWER.LOG(x)di SQLite berbasis 10.LN(x)adalah logaritma natural.LOG(b, x)dengan dua argumen adalah logaritma berbasisb. (Ini berbeda dari banyak bahasa yanglog-nya adalah logaritma natural; konvensi SQL yang dipakai di sini.)SQRTdari bilangan negatif menghasilkanNULL, bukan error.POWER(0, 0)mengembalikan1sesuai konvensi.
Fungsi-fungsi ini berguna untuk bunga majemuk, normalisasi ke desibel, menghitung jarak, dan di mana pun matematika geometris atau eksponensial muncul.
RANDOM dan RANDOMBLOB
RANDOM() mengembalikan integer 64-bit bertanda, di mana saja dalam seluruh rentangnya:
Untuk mendapatkan bilangan dalam sebuah rentang, bungkus dengan ABS (karena RANDOM() bertanda) lalu pakai %. Untuk mendapatkan bilangan real antara 0 dan 1, bagi dengan integer 64-bit terbesar. SQLite tidak punya RAND() bawaan yang mengembalikan 0 sampai 1, jadi kamu membuatnya sendiri.
RANDOMBLOB(n) mengembalikan n byte data acak, berguna untuk membuat token sesi atau data uji. Gabungkan dengan HEX() untuk mendapat string yang bisa dicetak:
Setiap pemanggilan menghasilkan nilai baru. Jangan harap RANDOM() mengembalikan angka yang sama dua kali di baris yang sama; bahkan di dalam satu ekspresi, setiap pemanggilan berdiri sendiri.
Menggabungkan Semuanya
Contoh kecil: menghitung jarak dan membulatkan harga untuk tabel produk.
price_cents / 100.0 adalah bagian kuncinya: .0 itu membuat pembagiannya menjadi real, lalu ROUND merapikannya menjadi dua angka desimal. Tanpanya, 1299 / 100 akan memberimu 12, bukan 12.99.
Selanjutnya: Tanggal dan Waktu
Fungsi numerik menangani matematika. Tanggal dan waktu butuh perangkatnya sendiri: SQLite menyimpannya sebagai teks, real, atau integer, dan memberimu sekumpulan fungsi yang kecil tapi mumpuni untuk mem-parse, memformat, dan berhitung dengannya. Itulah yang dibahas berikutnya.
Pertanyaan yang sering diajukan
Bagaimana cara membulatkan ke 2 angka desimal di SQLite?
Gunakan ROUND(value, 2). Argumen kedua adalah jumlah digit desimal yang dipertahankan: ROUND(3.14159, 2) mengembalikan 3.14. Dengan satu argumen, ROUND(x) membulatkan ke integer terdekat tapi tetap mengembalikan nilai floating-point, dan ini sering mengejutkan orang.
Apakah SQLite punya CEIL dan FLOOR?
Punya. Sejak SQLite 3.35 (2021), fungsi matematika sudah bawaan: CEIL(x), FLOOR(x), SQRT(x), POWER(x, y), LOG(x), EXP(x), dan kawan-kawannya. Di build yang lebih lama, fungsi-fungsi ini tidak tersedia kecuali ekstensi matematikanya dimuat. Kebanyakan instalasi modern (Python, Node, browser) sudah mengaktifkannya.
Kenapa 5 / 2 menghasilkan 2 di SQLite?
Karena kedua operannya integer, SQLite melakukan pembagian integer dan memotong hasilnya. Ubah salah satu sisi menjadi REAL, misalnya 5 / 2.0 atau CAST(5 AS REAL) / 2, untuk mendapatkan 2.5. Ini bukan keanehan fungsi numerik, melainkan perilaku operator / dengan argumen integer.