Menggunakan Array Di Google BigQuery
Salah satu cara untuk mendapatkan hasil query lebih cepat di BigQuery adalah dengan melakukan denormalisasi dengan menggunakan tipe data ARRAY. Sebagai contoh, saya akan membuat sebuah tabel baru bernama faktur dengan struktur seperti berikut ini:

Pada tabel di atas, field items adalah sebuah array yang terdiri atas satu atau lebih record. Tipe data dari items adalah STRUCT (RECORD)
sehingga items menyerupai sebuah tabel yang berada di dalam tabel faktur.
Saya bisa menambahkan beberapa data baru dengan menggunakan perintah SQL berikut ini:
INSERT INTO faktur VALUES ('F-001','2020-07-11 07:00:00', [ ('P-001', 10, NUMERIC '5000.00'), ('P-002', 20, NUMERIC '4000.00'), ('P-003', 5, NUMERIC '15000.00')]);
INSERT INTO faktur VALUES ('F-002','2020-07-11 08:00:00', [ ('P-002', 99, NUMERIC '3900.00')]);
INSERT INTO faktur VALUES ('F-003','2020-07-11 09:00:00', [ ('P-001', 1, NUMERIC '6000.00'), ('P-001', 2, NUMERIC '6000.00'), ('P-002', 1, NUMERIC '5000.00')]);
INSERT INTO faktur VALUES ('F-004','2020-07-11 09:00:00', [ ('P-003', 88, NUMERIC '10000.00')]);Untuk menyisipkan sebuah array, saya menggunakan kurung siku seperti [1,2,3,4,5]. Karena array tersebut memiliki tipe STRUCT, saya menggunakan tanda kurung untuk menyisipkan field sesuai dengan deklarasi STRUCT tersebut. Hasil DML di atas akan terlihat seperti berikut ini:

Salah satu operator yang paling sering dipakai bersama dengan array adalah UNNEST. Operator ini digunakan untuk melakukan flattening array sehingga
setiap item di array akan menjadi sebuah record. Sebagai contoh, untuk menerjemahkan setiap elemen array kolom items menjadi record terpisah, saya bisa menggunakan query seperti berikut ini:
SELECT items.kodeProduk, items.jumlah, items.hargaFROM fakturCROSS JOIN UNNEST(faktur.items) AS items;| kodeProduk | jumlah | harga |
|---|---|---|
| P-002 | 99 | 3900 |
| P-001 | 10 | 5000 |
| P-002 | 20 | 4000 |
| P-003 | 5 | 15000 |
| P-003 | 88 | 10000 |
| P-001 | 1 | 6000 |
| P-001 | 2 | 6000 |
| P-002 | 1 | 5000 |
Dengan demikian, saya bisa mendapatkan informasi seperti produk yang paling banyak dibeli dengan menggunakan query seperti:
SELECT items.kodeProduk, SUM(items.jumlah) AS jumlahFROM fakturCROSS JOIN UNNEST(faktur.items) AS itemsGROUP BY items.kodeProdukORDER BY jumlah DESC;| kodeProduk | jumlah |
|---|---|
| P-002 | 120 |
| P-003 | 93 |
| P-001 | 13 |
Bagaimana bila saya ingin mendapatkan daftar item beserta dengan jumlah yang harus dibayar untuk setiap faktur? Saya bisa menggunakan query berikut ini:
SELECT faktur.nomor, faktur.items, (SELECT SUM(item.jumlah * item.harga) FROM UNNEST(faktur.items) item) AS totalFROM faktur| nomor | items | total |
|---|---|---|
| F-001 | [{"kodeProduk":"P-001","jumlah":"10","harga":"5000"},{"kodeProduk":"P-002","jumlah":"20","harga":"4000"},{"kodeProduk":"P-003","jumlah":"5","harga":"15000"}] | 205000 |
| F-003 | [{"kodeProduk":"P-001","jumlah":"1","harga":"6000"},{"kodeProduk":"P-001","jumlah":"2","harga":"6000"},{"kodeProduk":"P-002","jumlah":"1","harga":"5000"}] | 23000 |
| F-002 | [{"kodeProduk":"P-002","jumlah":"99","harga":"3900"}] | 386100 |
| F-004 | [{"kodeProduk":"P-003","jumlah":"88","harga":"10000"}] | 880000 |
Setelah mendapatkan hasil di atas, saya juga bisa melakukan penyaringan lebih lanjut lagi dengan menggunakan WHERE. Sebagai contoh, query berikut ini akan memberikan hasil dengan struktur yang sama tetapi hanya untuk faktur yang mengandung kodeProduk dengan nilai P-003 saja:
SELECT faktur.nomor, faktur.items, (SELECT SUM(item.jumlah * item.harga) FROM UNNEST(faktur.items) item) AS totalFROM fakturWHERE EXISTS (SELECT 1 FROM UNNEST(faktur.items) AS item WHERE item.kodeProduk = 'P-003');| nomor | items | total |
|---|---|---|
| F-001 | [{"kodeProduk":"P-001","jumlah":"10","harga":"5000"},{"kodeProduk":"P-002","jumlah":"20","harga":"4000"},{"kodeProduk":"P-003","jumlah":"5","harga":"15000"}] | 205000 |
| F-004 | [{"kodeProduk":"P-003","jumlah":"88","harga":"10000"}] | 880000 |
Pada kondisi tertentu, saya tidak membutuhkan seluruh detail di kolom items. Bagaimana bila saya hanya ingin mengetahui produk apa saja yang
tertera dalam faktur? Untuk mengubah array menjadi teks, saya bisa menggunakan function ARRAY_TO_STRING seperti pada contoh berikut ini:
SELECT faktur.nomor, ARRAY_TO_STRING(ARRAY(SELECT DISTINCT item.kodeProduk FROM UNNEST(faktur.items) item), ', ') AS daftarProdukFROM faktur| nomor | daftarProduk |
|---|---|
| F-001 | P-001, P-002, P-003 |
| F-002 | P-002 |
| F-003 | P-001, P-002 |
| F-004 | P-003 |