10 Tanda Datamu Bermasalah Sebelum Sempat Dianalisis
TL;DR
Data bermasalah biasanya ketahuan dari 10 tanda: baris duplikat, kolom kosong, format tanggal campur, satuan beda, kategori dobel nama, angka negatif di kolom yang harusnya positif, total yang gak cocok sama sumber, ID yatim, outlier ekstrem, dan timestamp masa depan. Semua bisa dicek pakai query SQL pendek sebelum satu chart pun dibuat.
Data bermasalah hampir selalu ngasih tanda sebelum kamu sempat bikin satu chart pun. Baris duplikat, kolom kosong, tanggal masa depan, kategori yang ditulis tiga versi berbeda.
Masalahnya, tanda-tanda ini gak muncul sendiri di layar. Kamu harus nyari.
Aku pernah kelewat satu tanda doang dan hasilnya laporan penjualan Q3 salah 14 persen. Bukan karena rumusnya keliru, tapi karena ada 812 baris duplikat yang ikut ke-SUM.
Berikut sepuluh tanda yang paling sering muncul, plus query buat ngecek masing-masing.
Kenapa harus cek data sebelum dianalisis?
Karena kesalahan di data mentah bakal kebawa ke setiap angka setelahnya. Satu baris duplikat bikin total penjualan naik. Satu tanggal salah format bikin tren bulanan bergeser. Analisis paling rapi pun gak bisa nyelametin input yang rusak, dan biasanya baru ketahuan pas laporan udah dipresentasiin ke atasan.
Pengecekan ini bagian dari data quality, yaitu praktik mastiin data layak dipakai buat ambil keputusan. Gak butuh tool mahal. Sepuluh query pendek udah cukup buat nangkep mayoritas masalah.
Tanda 1: Ada baris duplikat
Duplikat muncul gara-gara export dobel, sinkronisasi yang jalan dua kali, atau kasir yang nge-submit ulang waktu koneksi lemot. Efeknya paling terasa di angka total dan rata-rata.
SELECT id_transaksi, COUNT(*) AS jumlah
FROM toko_berkah.transaksi
GROUP BY id_transaksi
HAVING COUNT(*) > 1;
Kalau hasilnya kosong, aman. Kalau keluar baris, catat berapa banyak sebelum kamu hapus. Angka itu penting buat ngejelasin kenapa total kamu beda sama total sistem.
Tanda 2: Kolom kunci banyak yang kosong
Kolom kosong di field pendukung masih bisa ditolerir. Kolom kosong di ID pelanggan atau tanggal transaksi bikin analisis apa pun jadi gak valid.
SELECT
COUNT(*) AS total_baris,
COUNT(*) - COUNT(id_pelanggan) AS pelanggan_kosong,
COUNT(*) - COUNT(kota) AS kota_kosong,
COUNT(*) - COUNT(total_bayar) AS bayar_kosong
FROM toko_berkah.transaksi;
COUNT dengan nama kolom cuma ngitung nilai yang gak NULL. Selisihnya sama COUNT(*) adalah jumlah yang kosong. Cara ini jalan di hampir semua database, sesuai perilaku standar fungsi agregat yang dijelasin di dokumentasi PostgreSQL.
Tanda 3: Format tanggal campur aduk
Ini tanda paling licik. Data dari kasir pakai format 25/12/2025, data dari marketplace pakai 2025-12-25, dan ada satu file lagi pakai Dec 25, 2025.
Kalau kolomnya bertipe teks, database gak akan protes. Chart kamu yang bakal ngaco karena urutan bulannya acak.
Cek dengan lihat panjang karakter yang berbeda-beda:
SELECT LENGTH(tanggal_teks) AS panjang, COUNT(*) AS baris
FROM toko_berkah.transaksi_raw
GROUP BY LENGTH(tanggal_teks)
ORDER BY baris DESC;
Lebih dari satu nilai panjang? Berarti formatnya belum seragam.
Tanda 4: Satuan angka gak konsisten
Kolom berat isinya campuran gram dan kilogram. Kolom harga campuran rupiah penuh dan rupiah dalam ribuan. Ini sering kejadian waktu dua sumber digabung tanpa dicek.
Gejalanya kelihatan dari sebaran yang aneh, misalnya ada harga 25 dan ada harga 25000 buat produk yang sama. Cek pakai rentang nilai per produk:
SELECT id_produk,
MIN(harga_satuan) AS harga_min,
MAX(harga_satuan) AS harga_max
FROM toko_berkah.transaksi
GROUP BY id_produk
HAVING MAX(harga_satuan) > MIN(harga_satuan) * 100;
Tanda 5: Satu kategori punya banyak nama
"Bandung", "bandung", "Bandung " dengan spasi di belakang. Buat kamu itu satu kota. Buat GROUP BY itu tiga kota berbeda.
SELECT LOWER(TRIM(kota)) AS kota_bersih,
COUNT(DISTINCT kota) AS varian_penulisan,
COUNT(*) AS baris
FROM toko_berkah.transaksi
GROUP BY LOWER(TRIM(kota))
HAVING COUNT(DISTINCT kota) > 1;
Query ini nunjukin kota mana yang punya lebih dari satu cara penulisan. Perbaikannya gampang, yang susah itu nyadar masalahnya ada.
Tanda 6: Angka negatif di tempat yang salah
Qty negatif, total bayar negatif, umur pelanggan negatif. Kadang ini valid karena retur, tapi lebih sering karena salah input atau kolom yang ketuker.
SELECT COUNT(*) AS baris_negatif
FROM toko_berkah.transaksi
WHERE total_bayar < 0 OR qty < 0;
Kalau ternyata retur beneran, pastiin ada kolom penanda transaksinya. Jangan biarkan retur dan salah input campur di satu kolom yang sama.
Tanda 7: Total kamu gak cocok sama sumbernya
Ini pengecekan paling sederhana dan paling sering dilewat. Ambil total penjualan bulan lalu dari query kamu, terus bandingin sama angka yang keluar dari sistem kasir atau laporan finance.
Beda 0,1 persen masih wajar karena pembulatan. Beda 5 persen berarti ada yang hilang atau kehitung dobel di salah satu sisi.
Kalau kamu kerja di spreadsheet, SUMIF bisa dipakai buat ngitung total per bulan lalu dibandingin manual sama laporan resmi.
Tanda 8: Ada ID yatim
ID produk di tabel transaksi yang gak ada di tabel produk. Artinya ada produk yang kehapus, atau ada typo di ID.
SELECT t.id_produk, COUNT(*) AS baris
FROM toko_berkah.transaksi t
LEFT JOIN toko_berkah.produk p ON p.id_produk = t.id_produk
WHERE p.id_produk IS NULL
GROUP BY t.id_produk;
Kalau kamu lanjut analisis pakai INNER JOIN, baris-baris ini bakal hilang diam-diam. Total penjualan kamu jadi lebih kecil dari kenyataan tanpa ada peringatan apa pun.
Tanda 9: Ada nilai ekstrem yang gak masuk akal
Satu transaksi Rp980.000.000 di toko kelontong yang rata-rata transaksinya Rp47.000. Ini outlier, nilai yang jauh menyimpang dari sebaran normal.
SELECT id_transaksi, total_bayar
FROM toko_berkah.transaksi
WHERE total_bayar > (SELECT AVG(total_bayar) + 3 * STDDEV_SAMP(total_bayar)
FROM toko_berkah.transaksi)
ORDER BY total_bayar DESC;
Gak semua outlier itu salah. Bisa aja beneran ada pembelian borongan buat hajatan. Yang penting kamu tau dia ada sebelum dia ngerusak rata-rata.
Tanda 10: Ada timestamp dari masa depan
Transaksi tercatat tanggal 12 Maret 2027 padahal sekarang Desember 2025. Biasanya gara-gara zona waktu server, atau jam di perangkat kasir yang salah setel.
SELECT COUNT(*) AS tanggal_aneh
FROM toko_berkah.transaksi
WHERE tanggal > CURRENT_DATE OR tanggal < DATE '2020-01-01';
Batas bawahnya kamu sesuaikan sama tanggal toko mulai beroperasi. Apa pun yang di luar rentang itu patut dicurigai.
Contoh kasus: audit data toko_berkah
Aku jalanin sepuluh pengecekan ini ke dataset toko_berkah, 18.400 baris transaksi dari Januari sampai November 2025. Hasilnya:
| Tanda | Baris kena | % dari total |
|---|---|---|
| Duplikat id_transaksi | 812 | 4,4% |
| id_pelanggan kosong | 1.203 | 6,5% |
| Kota dobel penulisan | 2.940 | 16,0% |
| total_bayar negatif | 37 | 0,2% |
| ID produk yatim | 64 | 0,3% |
| Outlier di atas 3 SD | 21 | 0,1% |
| Tanggal masa depan | 9 | 0,05% |
Yang bikin kaget bukan angka duplikatnya, tapi kota dobel penulisan yang kena 16 persen baris. Sebelum dibersihin, laporan per kota nampilin 31 kota. Setelah TRIM dan LOWER, ternyata cuma 19 kota beneran.
Dua belas kota "hantu" itu muncul karena spasi dan kapital. Kalau laporan itu dipakai buat mutusin lokasi cabang baru, keputusannya bakal salah sasaran.
Total penjualan setelah duplikat dibuang turun dari Rp1,42 miliar jadi Rp1,36 miliar. Selisih Rp62 juta yang tadinya bakal masuk ke slide presentasi.
Kesalahan umum waktu ngecek data
- Langsung hapus tanpa catat. Simpan dulu jumlah baris yang kamu buang dan alasannya. Nanti pasti ada yang nanya.
- Cuma cek sekali di awal. Data masuk terus tiap hari. Pengecekan yang cuma jalan sekali gak nolong bulan depan.
- Nganggep NULL sama dengan nol. Kolom bayar yang NULL artinya belum diisi, bukan gratis. Bedanya besar buat rata-rata.
- Bersihin di query, bukan di sumber. Kalau masalahnya dari input kasir, benerin prosesnya. Kalau cuma ditambal di query, tiap orang yang narik data bakal dapet angka beda.
- Percaya sama tipe kolom. Kolom bernama tanggal belum tentu bertipe date. Cek dulu skemanya.
FAQ
Berapa lama waktu ideal buat cek kualitas data?
Buat tabel di bawah 1 juta baris, 15 sampai 20 menit udah cukup buat jalanin sepuluh query pengecekan di artikel ini. Simpan query-nya jadi satu file, terus jalanin tiap kali kamu terima dump data baru. Yang makan waktu itu bukan ngejalaninnya, tapi mutusin mana masalah yang harus diperbaiki di sumber dan mana yang cukup difilter di query.
Kalau datanya cuma di Excel, gimana cara ceknya?
Prinsipnya sama. Duplikat kamu cek pakai COUNTIF, kolom kosong pakai COUNTBLANK, kategori dobel nama pakai UNIQUE plus TRIM. Yang beda cuma alatnya. Untuk data di atas 100 ribu baris, Excel bakal berat dan lebih enak dipindah ke database dulu sebelum dicek.
Apa bedanya data kotor sama data yang salah?
Data kotor itu formatnya berantakan tapi informasinya masih benar, misalnya kota ditulis "Bandung" dan "bandung". Data salah itu isinya memang keliru, misalnya transaksi tercatat Rp5.000.000 padahal aslinya Rp500.000. Data kotor bisa kamu benerin sendiri lewat query. Data salah harus dikonfirmasi ke orang yang input.
Perlu gak sih bikin dokumentasi hasil pengecekan?
Perlu, dan cukup satu tab spreadsheet. Isinya tanggal cek, nama tabel, tanda yang ketemu, jumlah baris kena, dan keputusan kamu. Waktu tiga bulan lagi ada yang nanya kenapa angka Oktober beda sama sistem, catatan ini yang nyelametin kamu dari tebak-tebakan.
Kalau semua tanda ini muncul, mending data-nya dibuang aja?
Jangan langsung dibuang. Hitung dulu berapa persen baris yang kena. Kalau di bawah 2 persen dan gak nyentuh kolom kunci, kamu bisa lanjut analisis sambil catat batasannya. Kalau di atas 10 persen atau kena kolom yang jadi dasar keputusan, hentikan dulu dan benerin di sumbernya.
Penutup
Sepuluh tanda ini bisa kamu cek dalam waktu kurang dari 20 menit. Simpan query-nya jadi satu file, jalanin tiap kali data baru masuk.
Dua hal yang paling sering nyelametin laporan: cek duplikat dan cek kota dobel penulisan. Dua itu doang udah nangkep sebagian besar masalah di dataset UMKM.
Mau versi query yang lebih lengkap plus penjelasan tiap baris? Lanjut ke SQL buat cek kualitas data. Kalau kamu udah pakai pipeline dan mau pengecekannya jalan otomatis, mampir ke dbt tests untuk kualitas data.
Mulai dari satu tabel yang paling sering kamu pakai. Jalanin query pertama hari ini juga.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Cara Membuat Pivot Dinamis di SQL (Panduan 2026)
Pivot dinamis di SQL ngubah baris jadi kolom tanpa kamu hardcode nama kolomnya. Ini cara bikinnya pakai CASE WHEN dan versi yang kolomnya ngikut data.
Menghitung YTD, QTD, dan MTD di SQL (Panduan 2026)
YTD, QTD, dan MTD ngukur total dari awal tahun, kuartal, atau bulan sampai hari ini. Ini cara ngitungnya di SQL pakai DATE_TRUNC, plus satu query gabungan.
Gap and Island Analysis di SQL
Gap and island analysis di SQL nyari deret data yang berturut-turut (island) dan celah yang bolong (gap). Cocok buat hitung streak login atau cari tanggal transaksi yang hilang.