SUBQUERY-2 MI2154 SQL LANJUT Dedy Rahman Wijaya, S.T., M.T., OCA dedyrw@tass.telkomuniversity.ac.id
Sasaran Pembelajaran Mampu menulis multiple-column subquery Mampu menyelesaikan kasus menggunakan correlated subqueries Mampu menggunakan operator EXIST dan NOT EXISTS Mampu menggunakan klausa WITH
Multiple-Column Subqueries Single-Column Subqueries WHERE department_id IN (SELECT department_id FROM employees..) Multiple-Column Subqueries WHERE (manager_id, department_id) IN (SELECT manager_id, department_id FROM employees..)
Syntax: SELECT column, column,... FROM table WHERE (column, column,...) IN (SELECT column, column,... FROM table WHERE condition);
Mekanisme Pembandingan Kolom Pairwise comparisons Nonpairwise comparisons
Pairwise&NonPairwise Comparison Subquery Menampilkan pegawai yang bekerja pada department dan memiliki manager yang sama dengan pegawai 199 dan 174 Pairwise SELECT employee_id, manager_id, department_id, first_name FROM employees WHERE (manager_id, department_id) IN (SELECT manager_id, department_id FROM employees WHERE employee_id IN (199,174)) AND employee_id NOT IN (199,174) ORDER BY employee_id; VS NonPairwise SELECT employee_id, manager_id, department_id, first_name FROM employees WHERE manager_id IN(SELECT manager_id FROM employees WHERE employee_id IN (199,174)) AND department_id IN (SELECT department_id FROM employees WHERE employee_id IN (199,174)) AND employee_id NOT IN (199,174) ORDER BY employee_id;
Correlated Subqueries Correlated subquery menggunakan pemrosesan data baris per baris Subquery dieksekusi untuk setiap data pada kueri induknya
Correlated Subqueries SELECT employee_id, last_name FROM employees outer WHERE salary > (SELECT avg(salary) FROM employees WHERE outer.department_id=department_id) ORDER BY employee_id
Correlated UPDATE Menggunakan subquery untuk meng-update data pada suatu tabel berdasarkan data pada tabel lain
Correlated DELETE Menggunakan subquery untuk menghapus data pada suatu tabel berdasarkan data pada tabel lain
Menggunakan Operator EXISTS Operator EXISTS memeriksa apakah subquery menghasilkan data atau tidak. Jika subquery menghasilkan data maka: Proses pencarian data tidak dilanjutkan Kondisi di-set menjadi TRUE Jika subquery tidak menghasilkan data maka: Proses pencarian data dilanjutkan Kondisi di-set menjadi FALSE
Contoh Penggunaan Operator EXISTS
Klausa WITH Dengan menggunakan klausa WITH, kita dapat menggunakan blok query yang sama dalam statement SELECT pada saat terjadi lebih dari sekali pengambilan data dalam query yang kompleks. Klausa WITH mendapatkan hasil dari blok query dan menyimpannya dalam tablespace temporer milik user. Penggunaan klausa WITH dapat meningkatkan performansi karena pengambilan data hanya dilakukan sekali dan dapat digunakan berulang-ulang dalam satu perintah.
Kasus yang dapat diselesaikan menggunakan klausa WITH Dengan menggunakan klausa WITH, tuliskan query untuk menampilkan nama departemen dan total gaji bagi setiap departemen yang total gajinya lebih besar dari rata-rata seluruh gaji departemen yang ada. Solusi untuk permasalahan diatas: 1. Hitung total gaji untuk setiap departemen dan simpan hasilnya dengan menggunakan klausa WITH 2. Hitung rata-rata gaji seluruh departemen dan simpan hasilnya dengan menggunakan klausa WITH 3. Bandingkan total gaji yang telah dihitung dalam langkah pertama dengan rata-rata gaji yang dihitung dalam langkah kedua. Jika total gaji lebih besar dari rata-rata gaji maka tampilkan nama departemen dan total gaji bagi departemen tersebut.
Solusi tanpa menggunakan klausa WITH SELECT d.department_name, SUM(e.salary) AS dept_total FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name HAVING SUM(e.salary) > (SELECT SUM(dept_total)/COUNT(*) AS dept_avg FROM (SELECT d.department_name, SUM(e.salary) AS dept_total FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name)) Query Induk Subquery Query Induk = Subquery dan dipanggil lebih dari 1 X
Solusi menggunakan klausa WITH WITH dept_costs AS ( SELECT d.department_name, SUM(e.salary) AS dept_total FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name), avg_cost AS ( SELECT SUM(dept_total)/COUNT(*) AS dept_avg FROM dept_costs) SELECT * FROM dept_costs WHERE dept_total > (SELECT dept_avg FROM avg_cost) ORDER BY department_name;