qori.dev

Membuat query recursive untuk SQLite

· Qori El-Hafizh

Istilah recursive pada pemrograman digunakan apabila sebuah rutin memanggil rutin itu sendiri. Recursive berguna ketika kita perlu men-traverse data struktur berbentuk tree, linked list dari satu node ke node lain.

Apabila pada memory referensi ke node lain dapat berupa pointer, Pada sebuah tabel SQL referensi tersebut dapat berupa sebuah FOREIGN KEY yang menunjuk id row lain pada tabel yang sama.

Misal pada sebuah tabel employee

CREATE TABLE employee (
  	id INTEGER PRIMARY KEY,
	name TEXT,
  	manager INTEGER,
    FOREIGN KEY(manager) REFERENCES employee(id)
);

Tabel employee menunjukan daftar pegawai dan managernya. Yang apabila digambarkan dalam tree berbentuk:

Andi
  ├── Budi
  │   ├── David
  │   └── Evan
  └── Caca

Andi adalah root karena tidak memiliki manager diatasnya. Andi adalah manager dari Budi, Budi adalah manager dari David dan seterusnya.

Lalu bagaimana caranya untuk mengambil informasi seorang employee dan semua bawahannya?

Praktek

Buat tabel employee masukan data sample dengan query berikut

INSERT INTO employee(name, manager) 
VALUES 
	('Andi', NULL), 
	('Beni',1),
	('David',2),
	('Caca',1),
	('Evan',2);

Maka apabila sesuai table employee akan memiliki data sebagai berikut:

id name manager
1 Andi NULL
2 Beni 1
3 David 1
4 Caca 2
5 Evan 2

Dan inilah recursive query untuk mencari employee dengan suatu id = 1 (Andi) dan semua bawahannya.

WITH RECURSIVE
traverse(id, name, manager) AS (
 SELECT id, name, manager FROM employee WHERE employee.id = 1
 UNION ALL
 SELECT employee.id, employee.name, employee.manager 
  FROM employee JOIN traverse
  ON employee.manager = traverse.id
)
SELECT * FROM traverse;

Hasil run

| id  | name   | manager  |
|-----|--------|----------|
|  1  | Andi   | NULL     |
|  2  | Beni   | 1        |
|  3  | David  | 1        |
|  4  | Caca   | 2        |
|  5  | Evan   | 2        |

Apabila kita ingin mengambil Beni (id=2) dan semua bawahannya maka ganti employee.id pada SELECT id, name, manager FROM employee WHERE employee.id = 1 dengan 2 menjadi SELECT id, name, manager FROM employee WHERE employee.id = 2

Hasil run

| id  | name   | manager  |
|-----|--------|----------|
|  2  | Beni   | 1        |
|  3  | David  | 1        |
|  5  | Evan   | 2        |

Penjelasan

SELECT id, name, manager FROM employee WHERE employee.id = 1 adalah root dari query. Ini adalah employee atau node teratas pada pencarian. Ganti employee.id = 1 untuk menentukan root dari query ini.

Bagian recursive

UNION ALL
 SELECT employee.id, employee.name, employee.manager 
  FROM employee JOIN traverse
  ON employee.manager = traverse.id

Ketika me-UNION table employee dengan traverse. Dengan ON employee.manager = traverse.id kita mencari employee dimana managernya adalah employee yang sudah ada di dalam table traverse. Di dalam contoh ini, pada iterasi pertama sudah didapat andi dengan id 1. Maka pada traverse selanjutnya akan mengambil employee yang memiliki nilai manager yang sama dengan id Andi.