TL;DR
SQLite adalah database SQL yang seluruh datanya disimpan dalam satu file di komputer kamu, tanpa perlu install server atau bikin akun. Kamu tinggal bikin file baru, jalanin CREATE TABLE dan INSERT, terus langsung latihan SELECT, WHERE, JOIN, dan GROUP BY. Ini cara paling cepat buat pemula punya database sendiri buat latihan SQL, dan skill-nya langsung kepakai di MySQL atau PostgreSQL.
SQLite adalah database SQL yang seluruh isinya disimpan dalam satu file di komputer kamu. Nggak ada server yang harus dinyalain, nggak ada username dan password, nggak ada konfigurasi.
Buat pemula, ini penting. Alasan paling sering orang gagal mulai belajar SQL bukan karena query-nya susah, tapi karena kejebak dua jam di tahap install database dan nyerah duluan.
Di tutorial ini kamu bakal bikin database toko_berkah dari nol, isi datanya, terus latihan query sampai JOIN dan GROUP BY. Semuanya di laptop kamu sendiri, dalam 15 menit pertama.
SQLite adalah database engine yang jalan di dalam aplikasi kamu, bukan sebagai server terpisah. Satu database = satu file dengan ekstensi .db. Mau backup? Copy file-nya. Mau kirim ke temen? Kirim file-nya lewat WhatsApp.
Ini bukan mainan. SQLite ada di setiap HP Android dan iPhone, di browser Chrome, dan di ribuan aplikasi desktop. Menurut dokumentasi resmi SQLite, ini database yang paling banyak dipasang di dunia.
Buat kamu yang lagi belajar, tiga keuntungan konkretnya:
Ada tiga jalan. Pilih satu, gak usah semuanya.
Aplikasi gratis dengan tampilan tabel kayak Excel. Kamu bisa lihat isi tabel sambil nulis query. Download dari sqlitebrowser.org, ada buat Windows, Mac, dan Linux.
Kalau kamu baru mulai, pakai ini. Bisa lihat hasil query langsung dalam bentuk tabel itu bantu banget.
Mac dan Linux biasanya udah bawa sqlite3. Cek di terminal:
sqlite3 --version
Kalau keluar nomor versi, kamu udah siap. Buat bikin database baru:
sqlite3 toko_berkah.db
File toko_berkah.db langsung kebuat di folder itu.
Python udah bawa modul sqlite3 bawaan. Tiga baris ini udah bikin database:
import sqlite3
koneksi = sqlite3.connect("toko_berkah.db")
kursor = koneksi.cursor()
Tabel dibikin pakai perintah CREATE TABLE. Kamu sebutin nama kolom dan tipe datanya.
Kita bikin dua tabel buat toko_berkah: tabel produk dan tabel penjualan.
CREATE TABLE produk (
id_produk INTEGER PRIMARY KEY,
nama_produk TEXT NOT NULL,
kategori TEXT,
harga INTEGER NOT NULL
);
CREATE TABLE penjualan (
id_transaksi INTEGER PRIMARY KEY,
tanggal TEXT NOT NULL,
id_produk INTEGER NOT NULL,
jumlah INTEGER NOT NULL,
kasir TEXT,
FOREIGN KEY (id_produk) REFERENCES produk(id_produk)
);
Beberapa hal yang perlu kamu tau dari kode di atas:
INTEGER PRIMARY KEY bikin kolom itu jadi ID unik. Kalau kamu gak isi nilainya waktu INSERT, SQLite ngasih nomor urut otomatis.
NOT NULL artinya kolom itu wajib diisi. Coba masukin baris tanpa nama_produk, SQLite bakal nolak.
Tanggal disimpan sebagai TEXT. SQLite gak punya tipe DATE. Simpan pakai format YYYY-MM-DD, format itu bisa diurutkan dengan benar sebagai teks.
FOREIGN KEY nyambungin penjualan ke produk. Ini yang nanti bikin JOIN masuk akal.
Pakai INSERT INTO. Kamu bisa masukin banyak baris sekaligus, dipisah koma.
INSERT INTO produk (id_produk, nama_produk, kategori, harga) VALUES
(1, 'Beras 5kg', 'Sembako', 72000),
(2, 'Minyak Goreng 2L', 'Sembako', 38000),
(3, 'Gula Pasir 1kg', 'Sembako', 16000),
(4, 'Kopi Sachet', 'Minuman', 2500),
(5, 'Teh Celup 25s', 'Minuman', 9500);
INSERT INTO penjualan (tanggal, id_produk, jumlah, kasir) VALUES
('2026-06-01', 1, 3, 'Wati'),
('2026-06-01', 4, 24, 'Wati'),
('2026-06-01', 2, 2, 'Wati'),
('2026-06-02', 3, 5, 'Dedi'),
('2026-06-02', 4, 40, 'Dedi'),
('2026-06-02', 1, 1, 'Dedi'),
('2026-06-03', 5, 12, 'Wati'),
('2026-06-03', 4, 30, 'Wati'),
('2026-06-03', 2, 4, 'Wati'),
('2026-06-04', 1, 2, 'Dedi'),
('2026-06-04', 3, 8, 'Dedi'),
('2026-06-04', 4, 18, 'Dedi');
Perhatiin: di INSERT penjualan aku gak isi id_transaksi. SQLite ngisi sendiri 1 sampai 12.
Cek hasilnya:
SELECT * FROM penjualan;
Kalau keluar 12 baris, database kamu udah jadi.
SELECT buat milih kolom yang mau ditampilkan. WHERE buat nyaring baris.
-- Produk yang harganya di bawah 20 ribu
SELECT nama_produk, harga
FROM produk
WHERE harga < 20000
ORDER BY harga;
Hasilnya:
| nama_produk | harga |
|---|---|
| Kopi Sachet | 2500 |
| Teh Celup 25s | 9500 |
| Gula Pasir 1kg | 16000 |
ORDER BY ngurutin dari kecil ke besar. Mau kebalikannya? Tambahin DESC di belakangnya.
Latihan lain yang bisa kamu coba sendiri: cari semua transaksi yang dilayani kasir Wati, atau transaksi dengan jumlah di atas 10.
Pertanyaan yang bakal sering kamu dapet di kerjaan: "Kategori mana yang paling laku?"
Itu butuh GROUP BY, cara ngegrupkan baris yang punya nilai sama, terus dihitung bareng.
SELECT
kasir,
COUNT(*) AS jumlah_transaksi,
SUM(jumlah) AS total_barang
FROM penjualan
GROUP BY kasir;
Hasilnya:
| kasir | jumlah_transaksi | total_barang |
|---|---|---|
| Dedi | 6 | 74 |
| Wati | 6 | 75 |
Sama-sama 6 transaksi. Tapi angka ini belum jawab pertanyaan omzet, karena harga tiap produk beda. Buat itu kita butuh JOIN.
JOIN nyambungin dua tabel lewat kolom yang sama. Di sini id_produk ada di dua-duanya.
SELECT
j.tanggal,
p.nama_produk,
j.jumlah,
p.harga,
j.jumlah * p.harga AS total_harga
FROM penjualan AS j
JOIN produk AS p ON j.id_produk = p.id_produk
ORDER BY j.tanggal;
Sekarang tiap baris penjualan punya nama produk dan harganya. Kolom total_harga dihitung on the fly.
Gabungin sama GROUP BY, dan kamu bisa jawab pertanyaan omzet per kategori:
SELECT
p.kategori,
SUM(j.jumlah * p.harga) AS omzet
FROM penjualan AS j
JOIN produk AS p ON j.id_produk = p.id_produk
GROUP BY p.kategori
ORDER BY omzet DESC;
Jalanin query omzet per kategori di atas, hasilnya:
| kategori | omzet |
|---|---|
| Sembako | Rp 810.000 |
| Minuman | Rp 394.000 |
Sembako menang jauh. Tapi lihat sisi lain: Kopi Sachet kejual 112 bungkus dalam 4 hari, muncul di semua hari. Beras cuma kejual 6 karung.
SELECT
p.nama_produk,
SUM(j.jumlah) AS unit_terjual,
SUM(j.jumlah * p.harga) AS omzet,
COUNT(DISTINCT j.tanggal) AS muncul_di_berapa_hari
FROM penjualan AS j
JOIN produk AS p ON j.id_produk = p.id_produk
GROUP BY p.nama_produk
ORDER BY unit_terjual DESC;
Kopi Sachet nyumbang omzet Rp 280.000, 34 persen dari total omzet, dari produk yang harganya cuma Rp 2.500. Dan dia satu-satunya produk yang laku tiap hari.
Buat pemilik toko, ini angka yang berguna: kopi sachet gak boleh kehabisan stok, sementara beras bisa distok lebih tipis karena perputarannya lambat.
Itu insight dari 12 baris data. Bayangin apa yang bisa kamu temuin dari 12.000 baris.
Simpan tanggal pakai format 12/06/2026. Pas kamu ORDER BY, urutannya jadi ngaco karena SQLite ngebandingin sebagai teks. Pakai YYYY-MM-DD, selalu.
Lupa titik koma di akhir query. Di terminal sqlite3, tanpa titik koma dia nunggu terus. Kalau prompt kamu berubah jadi ...>, itu artinya query-nya belum kamu tutup.
Pakai kutip dua buat teks. Di SQL standar, teks pakai kutip satu: 'Wati'. Kutip dua dipakai buat nama kolom. SQLite agak longgar soal ini, tapi database lain nggak, biasain dari sekarang.
Kaget karena SQLite nerima tipe data yang salah. SQLite gak seketat database lain. Kamu bisa masukin teks ke kolom INTEGER dan dia nurut aja. Ini fitur, bukan bug. Tapi hati-hati, ini bisa nyembunyiin data kotor.
Kelupaan FOREIGN KEY gak aktif by default. SQLite gak ngecek foreign key kecuali kamu nyalain: PRAGMA foreign_keys = ON; di awal sesi.
SQLite nyimpen semua data di satu file dan jalan di dalam aplikasi kamu, tanpa server terpisah. MySQL dan PostgreSQL butuh proses server yang nyala terus dan nerima koneksi lewat jaringan. Buat latihan query, perintah SELECT, WHERE, JOIN, dan GROUP BY-nya hampir identik. Yang beda cuma fitur lanjutan kayak tipe data ketat, user permission, dan akses banyak orang sekaligus.
Cukup, selama yang nulis data gak banyak sekaligus. SQLite dipakai di hampir semua HP Android dan iPhone, di browser, dan di banyak aplikasi desktop. Batasnya ada di penulisan bersamaan: cuma satu proses yang bisa nulis dalam satu waktu. Buat web app dengan ratusan orang nulis barengan, pindah ke PostgreSQL.
Nggak banyak. Kalau mau lewat terminal, download sqlite3 dari situs resminya, satu file executable. Kalau mau versi klik-klik, pakai DB Browser for SQLite yang gratis dan punya tampilan tabel kayak Excel. Python juga udah bawa modul sqlite3 bawaan, jadi kamu bisa langsung import tanpa install apa pun.
SQLite gak punya tipe data DATE khusus. Cara yang dianjurkan dokumentasi resminya adalah simpan tanggal sebagai TEXT dengan format YYYY-MM-DD. Format itu bisa diurutkan dan dibandingkan dengan benar sebagai teks biasa. Jangan simpan sebagai 12/06/2026 karena urutannya bakal kacau pas kamu pakai ORDER BY.
Kepakai. Sekitar 90 persen sintaks yang dipakai sehari-hari sebagai analis (SELECT, WHERE, JOIN, GROUP BY, HAVING, ORDER BY, subquery, CTE, window function) jalan sama persis di SQLite dan di database kantor. Yang perlu kamu sesuaikan nanti cuma fungsi tanggal dan fungsi teks, karena tiap database punya nama sendiri buat itu.
Bikin sendiri pakai INSERT, kayak contoh toko_berkah di artikel ini. 20 baris udah cukup buat latihan JOIN dan GROUP BY. Kalau mau data lebih banyak, SQLite bisa impor CSV lewat perintah .import, jadi kamu bisa ambil dataset publik dari BPS atau Kaggle dan langsung masukin ke tabel.
Yang udah kamu punya sekarang:
Langkah berikutnya bukan nambah teori. Tambahin data sendiri, 20 baris penjualan lagi, satu tabel cabang, terus paksa diri kamu jawab pertanyaan baru pakai query.
Kalau mau latihan dengan dataset yang lebih besar dan soal yang dikoreksi otomatis, coba NgulikSQL. Editor-nya jalan di browser, jadi kamu bisa latihan dari HP pun.
Lanjut baca: ETL vs ELT buat tau ke mana data kamu bakal dipindahin setelah keluar dari SQLite.
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.