Operasi Interval dan Aritmetika Tanggal di SQL
TL;DR
Operasi interval di SQL adalah cara nambah atau ngurangin durasi waktu dari sebuah tanggal, misalnya tanggal + INTERVAL '7 days'. Di PostgreSQL, kamu pakai kata kunci INTERVAL langsung dengan operator tambah dan kurang. Di MySQL, fungsi DATE_ADD dan DATE_SUB ngerjain hal yang sama. Selisih dua tanggal di PostgreSQL cukup pakai pengurangan biasa, sedangkan MySQL pakai DATEDIF atau TIMESTAMPDIFF.
Aritmetika tanggal di SQL adalah nambah atau ngurangin durasi dari sebuah tanggal. Nambah 30 hari buat cari jatuh tempo, ngurangin sebulan buat periode lalu, atau ngitung jarak hari antar transaksi.
SQL punya operator INTERVAL yang bikin ini gampang. Tapi sintaksnya beda antara PostgreSQL dan MySQL, dan ada jebakan akhir bulan yang sering bikin hasil aneh.
Kamu bakal lihat cara nambah dan ngurangin tanggal, ngitung selisih, plus contoh jatuh tempo invoice pakai data nyata.
Apa itu operasi interval di SQL?
Operasi interval adalah perhitungan yang nambah atau ngurangin rentang waktu dari sebuah tanggal atau timestamp. Rentangnya bisa dalam satuan hari, minggu, bulan, atau tahun. Hasilnya tanggal baru. Contoh gampangnya: tanggal hari ini ditambah interval 7 hari ngasih tanggal minggu depan.
Beda sama selisih tanggal yang ngasih angka durasi, operasi interval ngasih tanggal. Dua-duanya sering dipakai bareng di laporan.
Gimana cara nambah dan ngurangin tanggal di PostgreSQL?
Di PostgreSQL, pakai kata kunci INTERVAL langsung dengan operator plus atau minus. Tulis durasinya sebagai teks, kayak INTERVAL '7 days' atau INTERVAL '1 month'. PostgreSQL ngerti satuan hari, minggu, bulan, dan tahun.
SELECT
tanggal_order,
tanggal_order + INTERVAL '30 days' AS jatuh_tempo,
tanggal_order - INTERVAL '1 month' AS periode_lalu
FROM invoice;
Kamu bisa gabung beberapa satuan sekaligus: INTERVAL '1 year 2 months'. PostgreSQL juga terima bentuk singkat kayak INTERVAL '30d', tapi bentuk lengkap lebih gampang dibaca tim.
Buat ngambil bagian tanggal dari hasilnya, pasangin sama fungsi EXTRACT di SQL.
Gimana cara aritmetika tanggal di MySQL?
MySQL nggak pakai operator plus buat tanggal. Gantinya, ada fungsi DATE_ADD dan DATE_SUB. Argumennya tanggal, lalu kata kunci INTERVAL dengan angka dan satuan. Hasilnya sama kayak PostgreSQL, cuma bentuknya fungsi.
SELECT
tanggal_order,
DATE_ADD(tanggal_order, INTERVAL 30 DAY) AS jatuh_tempo,
DATE_SUB(tanggal_order, INTERVAL 1 MONTH) AS periode_lalu
FROM invoice;
Perhatiin bedanya: di MySQL, satuannya nggak pakai kutip dan nggak jamak. Tulis INTERVAL 30 DAY, bukan '30 days'. Salah satu ini yang sering bikin query gagal pas pindah database.
Gimana cara hitung selisih dua tanggal?
Selisih tanggal ngasih durasi, bukan tanggal baru. Di PostgreSQL, cukup kurangin dua tanggal pakai operator minus, hasilnya jumlah hari. Di MySQL, pakai DATEDIF buat selisih hari atau TIMESTAMPDIFF buat satuan lain.
-- PostgreSQL: hasil dalam hari
SELECT tanggal_kirim - tanggal_order AS lama_proses
FROM invoice;
-- MySQL
SELECT DATEDIFF(tanggal_kirim, tanggal_order) AS lama_proses
FROM invoice;
Hati-hati, urutan argumen di DATEDIF MySQL kebalik dari yang keliatan: tanggal akhir dulu, baru tanggal awal. Kalau kebalik, hasilnya negatif. Buat ngitung jarak antar transaksi berturut-turut, teknik window function kayak LAG sering dipakai bareng selisih tanggal.
Contoh kasus: jatuh tempo invoice toko_berkah
Toko_berkah jual grosir ke warung dengan tempo bayar 30 hari. Ada tabel invoice berisi 860 transaksi kredit. Manajernya mau tau invoice mana yang udah lewat jatuh tempo per hari ini, biar bisa ditagih.
SELECT
no_invoice,
nama_warung,
tanggal_order,
tanggal_order + INTERVAL '30 days' AS jatuh_tempo,
CURRENT_DATE - (tanggal_order + INTERVAL '30 days')::date AS hari_telat
FROM invoice
WHERE tanggal_order + INTERVAL '30 days' < CURRENT_DATE
ORDER BY hari_telat DESC;
Query ini ngitung jatuh tempo, lalu nyaring yang udah lewat, terus ngurutin dari yang paling telat. Kolom hari_telat ngasih tau berapa hari lewatnya.
Hasilnya bikin kaget: dari 860 invoice, 143 udah lewat tempo (16,6%). Yang paling parah telat 87 hari. Total nilai piutang macet ini nyampe 12% dari omzet kredit bulan itu. Angka ini bikin manajernya nerapin reminder otomatis di hari ke-25, sebelum jatuh tempo.
Kesalahan umum di aritmetika tanggal SQL
Jebakan paling bikin bingung: nambah bulan di akhir bulan. Kalau kamu nambah 1 bulan ke 31 Januari, apa hasilnya? Nggak ada 31 Februari. PostgreSQL ngasih 28 Februari, mundur ke tanggal valid terakhir. Ini benar, tapi bikin pola tanggal jadi nggak konsisten kalau kamu nambah bulan berulang.
Jebakan kedua: nyampur tipe DATE dan TIMESTAMP. Nambah interval ke DATE ngasih DATE, tapi ke TIMESTAMP ngasih TIMESTAMP dengan jam-menit. Kalau kamu bandingin hasilnya sama tanggal polos, bisa meleset gara-gara komponen jam. Cast dulu pakai ::date kalau cuma butuh tanggal.
Jebakan ketiga: lupa beda sintaks MySQL dan PostgreSQL. Query yang jalan mulus di Postgres langsung error di MySQL gara-gara operator plus dan bentuk INTERVAL. Selalu cek database targetnya. Referensi lengkap ada di dokumentasi fungsi tanggal PostgreSQL.
FAQ
Apa beda INTERVAL di PostgreSQL dan MySQL?
Di PostgreSQL kamu pakai operator plus dan minus langsung, misalnya tanggal + INTERVAL '7 days', dengan satuan dalam kutip dan bentuk jamak. Di MySQL kamu pakai fungsi DATE_ADD dan DATE_SUB, dengan INTERVAL 7 DAY tanpa kutip dan tanpa huruf s. Hasilnya sama, tapi query nggak bisa dipindah begitu aja tanpa nyesuain sintaks.
Gimana cara nambah jam atau menit, bukan cuma hari?
Pakai satuan waktu yang lebih kecil di interval. Di PostgreSQL tulis INTERVAL '2 hours' atau INTERVAL '30 minutes', dan operasinya harus di kolom TIMESTAMP, bukan DATE, biar komponen jamnya kesimpan. Di MySQL pakai DATE_ADD dengan INTERVAL 2 HOUR. Kalau kolomnya DATE polos, tambahan jam bakal keabaikan.
Kenapa hasil nambah bulan di akhir bulan jadi aneh?
Karena nggak semua bulan punya jumlah hari yang sama. Nambah 1 bulan ke 31 Januari nggak bisa ngasih 31 Februari, jadi SQL mundur ke 28 atau 29 Februari. Ini bikin pola tanggal geser kalau kamu nambah bulan berulang dari tanggal 31. Kalau butuh tanggal akhir bulan konsisten, pakai fungsi kayak DATE_TRUNC lalu tambahin interval.
Gimana cara hitung umur atau selisih dalam tahun?
Di PostgreSQL pakai AGE lalu EXTRACT tahunnya, misalnya EXTRACT(YEAR FROM AGE(tanggal_lahir)). Di MySQL pakai TIMESTAMPDIFF(YEAR, tanggal_lahir, CURDATE()). Dua-duanya ngitung tahun penuh dan udah ngecek apakah ulang tahun sudah lewat, jadi hasilnya nggak meleset setahun.
Bisa nggak nambah interval yang disimpan di kolom?
Bisa. Kamu bisa simpan durasi di kolom bertipe INTERVAL (di PostgreSQL) atau angka hari, lalu tambahin ke kolom tanggal. Contohnya tanggal_order + tempo_hari * INTERVAL '1 day', di mana tempo_hari kolom angka. Ini berguna kalau tiap pelanggan punya tempo bayar beda-beda yang disimpan per baris.
Penutup
Aritmetika tanggal di SQL intinya operator INTERVAL: plus dan minus di PostgreSQL, DATE_ADD dan DATE_SUB di MySQL. Ingat jebakan akhir bulan dan beda tipe DATE sama TIMESTAMP.
Mau latihan query tanggal beneran sampai lancar? Coba tulis dan jalanin langsung di NgulikSQL.
Lanjut baca: menghitung umur dari tanggal lahir di SQL dan membuat tabel kalender di SQL.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Composite Index di SQL: Cara Kerja dan Urutan Kolom
Composite index itu index atas beberapa kolom sekaligus. Urutan kolomnya nentuin query mana yang kebantu, lewat aturan leftmost prefix.
Menghitung Stickiness (DAU/MAU) di SQL
Stickiness ngukur seberapa sering user balik lagi. Ini cara hitung DAU, MAU, dan rasio stickiness pakai SQL, plus contoh aplikasi UMKM.
Menghitung DAU dan MAU dengan SQL
DAU dan MAU dua metrik wajib buat produk digital. Ini cara hitungnya pakai SQL, lengkap query DISTINCT, per bulan, sampai rasio stickiness.