TL;DR
CAST SQL mengubah tipe data sebuah nilai, misalnya teks jadi angka atau angka jadi tanggal, dengan sintaks CAST(nilai AS tipe_baru). CAST adalah standar ANSI dan jalan di hampir semua database, sementara CONVERT khusus SQL Server dan MySQL dengan sintaks berbeda. Kalau nilai yang dikonversi gak valid, query bakal error, pakai TRY_CAST atau TRY_CONVERT biar hasilnya NULL, bukan gagal total.
CAST ngubah tipe data satu nilai jadi tipe lain. Sintaksnya CAST(nilai AS tipe_baru), dan ini bagian dari standar ANSI SQL, artinya jalan di PostgreSQL, MySQL, SQL Server, sampai BigQuery dengan cara nulis yang sama.
Kamu bakal butuh ini lebih sering dari yang kamu kira. Import CSV dari marketplace? Semua kolom masuk sebagai teks. Kolom total_bayar yang isinya angka tapi tipenya VARCHAR bikin SUM() langsung error.
Di sini aku bahas sintaks CAST, bedanya sama CONVERT, cara nangkep konversi yang gagal, dan satu jebakan performa yang sering bikin query jadi lambat tanpa ketahuan.
CAST adalah fungsi SQL yang mengubah tipe data sebuah nilai jadi tipe lain: teks jadi angka, angka jadi teks, teks jadi tanggal. Konversinya terjadi saat query jalan, dan gak mengubah data yang tersimpan di tabel.
SELECT CAST('1500000' AS DECIMAL(12,2));
-- Hasil: 1500000.00
SELECT CAST('2026-02-06' AS DATE);
-- Hasil: 2026-02-06
SELECT CAST(1500000 AS VARCHAR(20));
-- Hasil: '1500000'
PostgreSQL punya sintaks pendek pakai dua titik dua:
SELECT total_bayar::DECIMAL(12,2) FROM transaksi_mentah;
Hasilnya sama persis dengan CAST. Cuma lebih cepat ngetiknya, dan cuma jalan di PostgreSQL.
CAST standar. CONVERT gak.
| CAST | CONVERT | |
|---|---|---|
| Standar ANSI | Ya | Nggak |
| Jalan di | Hampir semua database | SQL Server, MySQL (sintaks beda) |
| Sintaks | CAST(nilai AS tipe) | CONVERT(tipe, nilai, style) (SQL Server) |
| Format tanggal custom | Nggak bisa | Bisa, lewat kode style |
Nilai lebih CONVERT di SQL Server ada di argumen ketiga: kode style buat format tanggal.
-- SQL Server
SELECT CONVERT(VARCHAR, tanggal_order, 103) AS tgl_indo;
-- Hasil: 06/02/2026 (format dd/mm/yyyy)
SELECT CONVERT(VARCHAR, tanggal_order, 23) AS tgl_iso;
-- Hasil: 2026-02-06
Daftar lengkap kode style-nya ada di dokumentasi CAST dan CONVERT Microsoft. Kode 103 buat format Indonesia, 101 buat format Amerika.
Saran praktisnya: pakai CAST kecuali kamu butuh format tanggal khusus di SQL Server. Query kamu jadi bisa dipindah antar database tanpa ditulis ulang.
Tim toko_berkah nge-export laporan pesanan dari marketplace jadi CSV, terus di-import ke PostgreSQL. Masalahnya klasik: semua kolom masuk sebagai VARCHAR.
kode_order | total_bayar | jumlah_item | tanggal_order
ORD-2026-0001 | 1500000 | 3 | 2026-02-01
ORD-2026-0002 | 890000 | 2 | 2026-02-01
ORD-2026-0004 | 475000 | 1 | 2026-02-03
ORD-2026-0005 | N/A | 0 | 2026-02-03
Coba jumlahin omzet per kota, dan query-nya langsung nolak jalan:
SELECT kota, SUM(total_bayar) FROM transaksi_mentah GROUP BY kota;
-- ERROR: function sum(character varying) does not exist
CAST nyelesaiin itu:
SELECT
kota,
SUM(CAST(total_bayar AS DECIMAL(12,2))) AS total_omzet
FROM transaksi_mentah
GROUP BY kota
ORDER BY total_omzet DESC;
Tapi query di atas tetap error. Ada baris dengan nilai 'N/A', dan itu gak bisa jadi angka.
Dari 6 baris contoh, 1 baris rusak. Di dataset asli 12.400 baris, ada 187 baris dengan nilai 'N/A' atau string kosong, sekitar 1,5%. Cukup buat bikin seluruh laporan gagal jalan.
Cara paling bersih kalau kamu di SQL Server:
SELECT
kode_order,
TRY_CAST(total_bayar AS DECIMAL(12,2)) AS total
FROM transaksi_mentah;
-- Baris 'N/A' hasilnya NULL, query tetap jalan
Nilai yang gagal dikonversi jadi NULL, bukan bikin query mati. Kalau kamu belum akrab sama perilaku NULL di agregasi, baca dulu NULL di SQL. SUM otomatis ngelewatin NULL, jadi hasilnya tetap benar.
PostgreSQL gak punya TRY_CAST. Gantinya, cek dulu pakai CASE:
SELECT
kode_order,
CASE
WHEN TRIM(total_bayar) ~ '^[0-9]+(\.[0-9]+)?$'
THEN CAST(TRIM(total_bayar) AS DECIMAL(12,2))
ELSE NULL
END AS total_bersih
FROM transaksi_mentah;
Perhatiin TRIM di situ. Baris ORD-2026-0004 punya spasi di depan angkanya (' 475000'). Regex ^[0-9]+$ bakal nolak nilai itu karena karakter pertamanya spasi, bukan digit. Bersihin spasinya dulu, baru cek. Fungsi TRIM ngerjain itu.
Kalau data kotornya udah dibersihin dan kamu yakin semuanya valid, ubah tipe kolomnya permanen:
ALTER TABLE transaksi_mentah
ALTER COLUMN jumlah_item TYPE INTEGER
USING jumlah_item::INTEGER;
Sekali jalan, dan kamu gak perlu CAST lagi tiap nulis query. Ini jauh lebih enak daripada nempel CAST di 30 query berbeda.
Ini yang paling sering luput.
-- LAMBAT: index di kolom tanggal_order gak kepakai
SELECT * FROM transaksi
WHERE CAST(tanggal_order AS DATE) = DATE '2026-02-01';
-- CEPAT: kolomnya dibiarin apa adanya
SELECT * FROM transaksi
WHERE tanggal_order >= TIMESTAMP '2026-02-01 00:00:00'
AND tanggal_order < TIMESTAMP '2026-02-02 00:00:00';
Begitu kamu bungkus kolom pakai fungsi, database gak bisa pakai index yang ada di kolom itu. Dia terpaksa baca semua baris satu per satu, konversi tiap nilai, baru bandingin.
Aturannya: konversi nilai pembanding, bukan kolomnya. Kalau harus konversi kolom, bikin index terpisah di ekspresi hasil konversinya.
Pilih tipe target yang kekecilan. CAST(1500000 AS SMALLINT) bikin overflow karena SMALLINT maksimal 32.767. Kalau ragu, pakai INTEGER atau BIGINT.
Lupa presisi di DECIMAL. CAST(1234.567 AS DECIMAL(6,2)) ngasih 1234.57, dibulatin, gak error. Tapi CAST(12345.67 AS DECIMAL(6,2)) overflow, karena 6 digit total gak muat buat 5 digit di depan koma plus 2 di belakang.
Konversi tanggal tanpa mikirin format. String '06/02/2026' bisa jadi 6 Februari atau 2 Juni, tergantung setelan locale database. Pakai format ISO ('2026-02-06') buat semua konversi tanggal, dan kamu gak perlu nebak-nebak lagi.
CAST standar ANSI dan jalan di hampir semua database dengan sintaks yang sama. CONVERT cuma ada di SQL Server dan MySQL, dan sintaksnya beda di dua database itu. CONVERT versi SQL Server punya argumen style buat format tanggal, misal CONVERT(VARCHAR, tgl, 103) buat dd/mm/yyyy. Buat query yang portabel, pakai CAST.
CAST maksa konversi. Kalau ada satu nilai yang gak bisa dikonversi, teks 'N/A' ke DECIMAL, tanggal '31/02/2026' yang gak ada, database nolak seluruh query. Saring dulu pakai WHERE, atau pakai TRY_CAST yang ngasih NULL kalau gagal.
Pakai CAST(kolom AS DECIMAL) atau sintaks pendek kolom::DECIMAL. PostgreSQL gak punya TRY_CAST, jadi buat data kotor bungkus pakai CASE dengan cek regex. TRIM dulu sebelum dicek, soalnya spasi di depan angka bikin regex-nya gagal cocok.
Di SELECT dampaknya kecil. Yang bahaya CAST di WHERE pada kolom ber-index, database gak bisa pakai index-nya dan terpaksa scan seluruh tabel. Balik logikanya: konversi nilai pembanding, jangan kolomnya.
Ringkasnya: CAST buat query yang mau dipindah-pindah database, CONVERT kalau kamu di SQL Server dan butuh format tanggal khusus. Data hasil import selalu anggap kotor sampai terbukti bersih. TRY_CAST atau CASE + regex nyelametin laporan kamu dari mati mendadak gara-gara satu baris 'N/A'.
Dan jangan taruh CAST di WHERE kalau kolomnya punya index.
Coba query di bagian sql_queries artikel ini di database latihan kamu. Sengaja aku sisipin satu baris rusak dan satu baris berspasi, biar kamu ngerasain sendiri error-nya sebelum ketemu di kerjaan beneran.
Lanjut baca 12 fungsi string SQL buat ngerapiin teks sebelum dikonversi.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Analisa per kuartal, hari kerja, atau musim jadi ribet kalau tiap query ngitung ulang atribut tanggal. Tabel kalender nyimpen semua atribut itu sekali, biar tinggal di-JOIN.
Laporan penjualan harian sering bolong di hari tanpa transaksi. Ini cara bikin deret tanggal lengkap di SQL biar tiap hari muncul, walau nilainya nol.
Struktur organisasi tersimpan sebagai kolom id_atasan yang saling nunjuk. Ini cara narik rantai jabatan, hitung total bawahan, dan span of control cuma pakai SQL.