Analisis Data

Panduan Google Sheets QUERY SELECT: Agregasi & PIVOT

Marc Sean18 April 20269 menit baca

Di Google Sheets, QUERY(range, "SELECT a, b") mengembalikan dua kolom. Kalau di situ Anda berhenti, Anda melewatkan bagian yang membuat QUERY benar-benar berguna.

Klausul SELECT mendukung fungsi agregasi - SUM, COUNT, AVG, MAX, MIN - yang bisa dikombinasikan dengan GROUP BY dan PIVOT. Kombinasi ini mengubah tumpukan data transaksi mentah menjadi tabel ringkasan tanpa SUMIFS, tanpa kolom bantu, tanpa harus memperluas range setiap kali ada baris baru. Inilah bagian yang paling sering dilewati tutorial karena lebih sulit dijelaskan - dan justru bagian yang benar-benar mengubah cara Anda membangun model.

Penomoran Kolom Relatif terhadap Range, Bukan Sheet

Perlu dipahami sejak awal: a dalam formula QUERY bukan berarti kolom A di sheet. Artinya adalah kolom pertama dari range yang Anda masukkan ke QUERY. Jika range Anda adalah transaksi!C:H, maka a memetakan ke kolom C, b ke kolom D, dan seterusnya. Perilaku ini didokumentasikan dalam referensi Google Visualization API Query Language yang menjadi dasar fungsi QUERY di Google Sheets.

Ini penting terutama ketika data Anda tidak dimulai dari kolom A - yang hampir selalu terjadi. Tambahkan satu kolom di sebelah kiri range sumber, dan semua formula QUERY di bawahnya akan rusak tanpa pesan error. Perlu diantisipasi sejak desain awal.

Ada satu perilaku lain yang sering membingungkan: Anda bisa memfilter berdasarkan kolom tanpa menampilkannya di output. SELECT a, b WHERE c = 'Marketing' sepenuhnya valid - kolom c dipakai sebagai filter tapi tidak muncul di hasil. Banyak pengguna mengira kolom yang ada di WHERE harus ada juga di SELECT. Tidak harus.

SELECT dengan Agregasi di Google Sheets: Pengganti SUMIFS

Misalkan tab transaksi Anda memiliki 5 kolom: tanggal, divisi, kategori, vendor, jumlah. Anda ingin ringkasan per divisi dan kategori - jenis analisis yang biasanya dibangun dengan 20-an SUMIFS tersebar di matriks, masing-masing dikodekan keras untuk pasangan divisi-kategori tertentu.

=QUERY(transaksi!A:E,
  "SELECT B, C, SUM(E)
   WHERE A >= date '2026-01-01'
   GROUP BY B, C
   ORDER BY B, SUM(E) DESC
   LABEL SUM(E) 'Total'")

Satu formula ini membangun seluruh ringkasan. Divisi baru muncul otomatis. Kategori baru muncul otomatis. Filter tanggal mengecualikan data periode sebelumnya. Klausul LABEL di akhir mengganti nama kolom agregasi dari default QUERY (biasanya "sum jumlah") menjadi label yang mudah dibaca.

Pada log transaksi 10.000 baris, pendekatan ini berjalan sekitar 600ms - dibandingkan sekitar 1.100ms untuk matriks SUMIFS setara yang memindai range yang sama. Selisihnya semakin lebar seiring bertambahnya jumlah baris. Angka ini diukur pada Google Sheets per April 2026 menggunakan dataset sintetis dengan skema lima kolom dan distribusi nilai acak seragam.

Untuk menarik data P&L dari tab detail: tambahkan WHERE D = 'HPP' untuk mengisolasi baris biaya, atau hapus kolom kategori dari GROUP BY untuk meringkas per divisi saja. Satu formula, banyak tampilan.

PIVOT: Cross-Tab Tanpa Perlu Dibangun Ulang

Kata kunci PIVOT di QUERY membuat cross-tab yang otomatis diperbarui saat data sumber berubah, tanpa perlu menambah kolom secara manual.

=QUERY(transaksi!A:E,
  "SELECT B, SUM(E)
   WHERE A >= date '2026-01-01'
   GROUP BY B
   PIVOT C")

Baris adalah divisi. Kolom adalah nilai unik yang muncul di kolom C - secara dinamis. Anda tidak perlu menentukan kolom apa saja itu. QUERY membaca data dan membuat satu kolom per nilai unik. Untuk dataset pengeluaran yang terus bertambah kategorinya setiap kuartal, ini satu-satunya pendekatan yang tidak mengharuskan Anda menambah kolom secara manual setiap periode.

Satu keterbatasan nyata: header kolom PIVOT dihasilkan dari nilai data, sehingga sulit direferensikan dalam formula lanjutan. Jika output perlu digunakan untuk perhitungan berikutnya, GROUP BY saja adalah jalur yang lebih aman - tangani presentasi cross-tab secara terpisah.

Ketika Data Anda Tidak Bersih

Inilah yang jarang diceritakan tutorial QUERY: SELECT bekerja rapi pada data yang rapi. Data nyata merusaknya dengan cara yang spesifik dan sulit didiagnosis.

Inferensi tipe berjalan diam-diam. QUERY memindai sebagian awal kolom dan menentukan tipenya. Jika kolom jumlah Anda memiliki 4.997 angka dan 3 sel yang diisi "N/A" atau "pending" oleh seseorang, QUERY bisa mengklasifikasikan seluruh kolom sebagai string. Ketika itu terjadi, SUM(E) mengembalikan kosong - tanpa error, tanpa peringatan. Anda baru sadar ketika ringkasan tidak sesuai rekonsiliasi.

Solusinya: kolom bantu dengan =IFERROR(VALUE(E2), 0), yang mengubah "N/A" menjadi 0 dan membiarkan angka tetap apa adanya. Arahkan QUERY ke kolom bantu, bukan ke kolom aslinya.

Baris kosong menyebabkan masalah yang sama. Ekspor dari ERP dan database - SAP, Oracle, atau hampir semua ekspor CSV dari sistem lama - sering menyertakan baris kosong di antaranya. Baris ini memutus pemindaian deteksi tipe QUERY. Tambahkan WHERE E IS NOT NULL sebelum kondisi lain untuk menyaringnya. Mendefinisikan range sebagai kolom penuh (A:E) alih-alih range tetap seperti A1:E5000 juga membantu - QUERY menangani data jarang lebih baik pada range terbuka.

Format tanggal campuran adalah masalah paling parah. Klausul WHERE pada tanggal di QUERY mengharuskan format date 'YYYY-MM-DD'. Jika kolom tanggal berisi sebagian nilai yang tersimpan sebagai teks dan sebagian sebagai nilai tanggal sebenarnya, filter diam-diam tidak mengembalikan apapun. Uji dengan =TYPE(A2): nilai 1 berarti angka (nilai tanggal di Sheets disimpan sebagai angka - inilah yang Anda inginkan), nilai 2 berarti teks (bermasalah). Tanggal berformat teks perlu kolom bantu =DATEVALUE(A2) sebelum QUERY bisa memfilternya.

Pola kegagalannya selalu sunyi - hasil kosong, bukan pesan error. Sebelum mempercayai formula QUERY pada dataset nyata, jalankan SELECT COUNT(a) terlebih dahulu. Jika hitungannya tidak sesuai ekspektasi jumlah baris, ada yang salah dengan inferensi tipe sebelum Anda menyentuh query sebenarnya.

SELECT Dinamis: Laporan Berbasis Dropdown

Pola QUERY paling berguna untuk pelaporan adalah yang paling jarang didokumentasikan: membangun string SELECT dari referensi sel.

=QUERY(data!A:F,
  "SELECT " & B1 & " WHERE A >= date '2026-01-01'")

Jika B1 berisi "a, b, d", query mengembalikan kolom 1, 2, dan 4. Ubah B1 menjadi "a, c, f" dan output langsung berubah.

Kombinasikan ini dengan dropdown validasi data - sel tempat pengguna memilih "Tampilan Pendapatan" atau "Tampilan Biaya" - dan VLOOKUP yang memetakan setiap pilihan ke string kolom, dan Anda punya satu range output yang berubah konfigurasinya berdasarkan input pengguna. Tanpa Apps Script, tanpa menu kustom.

Versi praktisnya: jika berbagai pemangku kepentingan menginginkan subset kolom yang berbeda - tim keuangan ingin margin, operasional ingin jumlah SDM, eksekutif ingin KPI - pola ini melayani semuanya dari satu tab data tanpa harus mempertahankan 3 range output terpisah. Penambahan kolom tetap akan merusaknya - itulah keterbatasan mendasar dari pengalamatan kolom dengan huruf - tetapi untuk skema yang stabil, ini adalah solusi paling bersih yang tersedia dalam formula.

QUERY Google Sheets vs FILTER vs VLOOKUP

KebutuhanAlat terbaikEstimasi waktu pada 10.000 baris
Mengembalikan baris berdasarkan kondisiQUERY atau FILTER~400ms (serupa)
Merangkum per grup (pengganti matriks SUMIFS)QUERY GROUP BY~600ms vs ~1.100ms untuk SUMIFS setara
Output cross-tabQUERY PIVOT~900ms
Pencarian nilai tunggal berdasarkan kunciVLOOKUP / INDEX-MATCH~80ms
Pemilihan kolom dinamisQUERY dengan penggabungan stringSama dengan query dasar
Filter baris dengan regex / pencocokan sebagianQUERY (kata kunci MATCHES)~700ms

VLOOKUP unggul jauh untuk pencarian nilai tunggal - lebih cepat dan formulanya lebih mudah diaudit. FILTER lebih baik dari QUERY untuk seleksi baris kondisional ketika Anda tidak butuh agregasi, karena sintaksnya lebih transparan dan menangani kondisi array secara alami. QUERY mengambil alih ketika Anda butuh GROUP BY, PIVOT, atau pemilihan kolom teragregasi. Menggunakan QUERY untuk pencarian nilai tunggal sederhana ibarat naik tol hanya untuk pergi ke warung sebelah.

Studi Kasus Nyata: Ekspor Transaksi → Ringkasan Bulanan

Pola di atas menjadi konkret di sini. Misalkan Anda memiliki tab bernama data_transaksi dengan kolom: tanggal, id_pelanggan, nilai_mrr, paket, status. Anda ingin ringkasan bulanan per paket di tab pelaporan terpisah.

=QUERY(data_transaksi!A:E,
  "SELECT 
     YEAR(A), MONTH(A), D,
     SUM(C)
   WHERE E = 'aktif'
   GROUP BY YEAR(A), MONTH(A), D
   ORDER BY YEAR(A), MONTH(A), D
   LABEL YEAR(A) 'Tahun', MONTH(A) 'Bulan', D 'Paket', SUM(C) 'MRR'")

Formula ini menghasilkan tabel 4 kolom: tahun, bulan, paket, MRR. Setiap kali tab data transaksi diperbarui, formula ini ikut menghitung ulang. Tidak perlu formula tambahan, tidak perlu memperluas matriks SUMIFS ketika paket baru ditambahkan.

Kendalanya: jika kolom nilai_mrr memiliki bahkan satu nilai non-numerik - skrip ekspor yang menulis "null" atau "-" alih-alih 0 - SUM mengembalikan kosong untuk seluruh kolom. Bungkus sumbernya: =IFERROR(VALUE(C2), 0) di kolom bantu, lalu arahkan QUERY ke kolom bantu tersebut.

Per April 2026, fungsi YEAR() dan MONTH() di QUERY bekerja pada sel berformat tanggal, tetapi tidak pada string teks yang tampak seperti tanggal. Jika ekspor Anda menulis tanggal sebagai teks ("2026-01-15" alih-alih nilai tanggal Sheets), tambahkan kolom bantu dengan =DATEVALUE(A2) dan referensikan itu.

Ketika penomoran kolom pada range lebar mulai membingungkan - yang terjadi dengan cepat pada ekspor 15 kolom - Coba ModelMonkey gratis 14 hari untuk Google Sheets dan Excel.

FAQ: Google Sheets QUERY SELECT

Mengapa SUM di QUERY mengembalikan hasil kosong meskipun kolom berisi angka?

Penyebab paling umum adalah inferensi tipe yang gagal. Jika ada satu pun sel di kolom tersebut berisi teks - termasuk "N/A", "null", atau sel kosong yang sebenarnya berisi spasi - QUERY bisa mengklasifikasikan seluruh kolom sebagai string, sehingga SUM tidak bisa beroperasi. Solusinya: buat kolom bantu dengan =IFERROR(VALUE(sel), 0) dan arahkan QUERY ke kolom bantu itu. Sebelum debugging lebih jauh, uji dengan SELECT COUNT(a) untuk memastikan QUERY bisa membaca baris sama sekali.

Apakah kolom yang ada di WHERE harus dicantumkan juga di SELECT?

Tidak. SELECT a, b WHERE c = 'Marketing' sepenuhnya valid - kolom c digunakan sebagai filter tetapi tidak muncul di output. Ini berlaku juga untuk GROUP BY dan ORDER BY: kolom yang digunakan dalam klausa tersebut tidak wajib ada di SELECT.

Kenapa formula QUERY tiba-tiba rusak setelah saya menambah kolom baru di sheet?

Karena pengalamatan kolom di QUERY (a, b, c, dst.) bersifat relatif terhadap range, bukan terhadap posisi kolom di sheet. Jika Anda menambah kolom di sebelah kiri range sumber, semua huruf kolom bergeser satu posisi dan formula Anda membaca kolom yang salah - tanpa pesan error. Antisipasi ini dengan menetapkan range QUERY se-spesifik mungkin, atau dokumentasikan pemetaan kolom di komentar sel.

Apa perbedaan utama antara QUERY PIVOT dan membuat cross-tab manual?

QUERY PIVOT menghasilkan kolom secara dinamis berdasarkan nilai unik di kolom data - Anda tidak perlu tahu terlebih dahulu ada berapa kolom yang akan muncul. Cross-tab manual (dengan SUMIFS atau GETPIVOTDATA) mengharuskan Anda menambah kolom secara manual setiap kali kategori baru muncul. Kekurangan PIVOT: header kolomnya sulit direferensikan dalam formula lanjutan karena dihasilkan dari nilai data, bukan dari nama yang Anda tentukan.

Apakah fungsi YEAR() dan MONTH() di QUERY bisa dipakai untuk semua format tanggal?

Hanya untuk sel yang menyimpan tanggal sebagai nilai angka (format tanggal asli Google Sheets). Jika tanggal tersimpan sebagai teks - yang sering terjadi pada ekspor CSV - fungsi ini tidak bekerja dan filter tanggal akan mengembalikan hasil kosong. Gunakan =TYPE(sel): nilai 1 berarti angka (baik), nilai 2 berarti teks (perlu konversi dengan =DATEVALUE(sel) di kolom bantu).