[Belajar SQL](http://pojokprogrammer.net/tags/belajar-sql) | Setelah sebelumnya kita anatomi dan penggunaan perintah SQL SELECT untuk melakukan proses temu kembali data (*data retrieval*), maka langkah selanjutnya kita harus mempertajam ***Skill SQL***, dengan memperbanyak latihan, dan salah satu cara untuk melatih *skill SQL* adalah dengan cara mencoba membantu menyelesaikan problem SQL yang dihadapi orang lain. Beberapa situs yang bisa kita kunjungi untuk melatih *skill SQL* adalah [Oracle Community Forum](https://community.oracle.com/community/database/developer-tools/sql_and_pl_sql), namun berbahasa Inggris. Sedangkan untuk yang berbahasa Indonesia bisa mengunjungi [Programmer Forum di Kaskus](https://www.kaskus.co.id/thread/000000000000000007584619/sql-yang-punya-problem-sql-kumpul-disini-gan-no-urgent-please/). Dalam artikel ini kita akan membahas beberapa kasus berkaitan dengan SQL JOIN.
**Bagian kelima dari rangkaian artikel tentang [Konsep Database Relasional](http://pojokprogrammer.net/content/konsep-database-relasional-dan-bahasa-sql)**
[Belajar SQL](http://pojokprogrammer.net/tags/belajar-sql) | Setelah sebelumnya kita anatomi dan penggunaan perintah SQL SELECT — atau biasa disebut sebagai *query* — untuk melakukan proses temu kembali data (*data retrieval*), maka langkah selanjutnya kita harus mempertajam ***Skill SQL***, dengan memperbanyak latihan, dan salah satu cara untuk melatih skill SQL adalah dengan cara mencoba membantu menyelesaikan problem SQL yang dihadapi orang lain. Beberapa situs yang bisa kita kunjungi untuk melatih skill SQL adalah [Oracle Community Forum](https://community.oracle.com/community/database/developer-tools/sql_and_pl_sql), namun berbahasa Inggris. Sedangkan untuk yang berbahasa Indonesia bisa mengunjungi [Programmer Forum di Kaskus](https://www.kaskus.co.id/thread/000000000000000007584619/sql-yang-punya-problem-sql-kumpul-disini-gan-no-urgent-please/). Dalam artikel ini kita akan membahas beberapa kasus berkaitan dengan SQL JOIN.
Untuk menyelesaikan kasus-kasus yang dibahas dalam artikel ini, silakan buka laptop atau komputer masing-masing, jalankan MySQL, kemudian buat sebuah database baru dan eksekusi [perintah SQL berikut ini](https://gist.github.com/hidayat365/29f9f544930621f12413c9a7856b17ab)
###Data yang Kita Gunakan
Data Mahasiswa, adalah sebagai berikut
MariaDB [test]> select * from students; +----+---------+------------------+ | id | code | name | +----+---------+------------------+ | 1 | 2016001 | David Beckam | | 2 | 2016002 | Alexis Sanchez | | 3 | 2016003 | Mesut Oezil | | 4 | 2016004 | Lionel Messi | | 5 | 2016005 | Andres Iniesta | | 6 | 2016006 | Hector Bellerin | | 7 | 2016007 | Sergio Aguero | | 8 | 2016008 | David Silva | | 9 | 2016009 | Andik Firmansyah | | 10 | 2016010 | Boaz Sallosa | +----+---------+------------------+ 10 rows in set (0.00 sec)
Data Mata Kuliah, adalah sebagai berikut
MariaDB [test]> select * from courses; +----+--------+---------------------+ | id | code | name | +----+--------+---------------------+ | 1 | MKU001 | Kewarganegaraan | | 2 | MKU002 | Bahasa Inggris | | 3 | MKU003 | Bahasa Indonesia | | 4 | IKI001 | Konsep Pemrograman | | 5 | IKI002 | Sistem Basis Data | | 6 | IKI003 | Sistem Operasi | | 7 | IKI004 | Grafika Komputer | | 8 | IKI005 | Matematika Diskrit | | 9 | AST006 | Astronomi Dasar | | 10 | AST007 | Astronomi Komputasi | +----+--------+---------------------+ 10 rows in set (0.00 sec)
Data Mata Kuliah yang diambil oleh Mahasiswa, adalah sebagai berikut
MariaDB [test]> select * from student_courses; +----+----------+------------+-----------+ | id | semester | student_id | course_id | +----+----------+------------+-----------+ | 1 | 1 | 1 | 1 | | 2 | 1 | 1 | 2 | | 3 | 1 | 1 | 5 | | 4 | 1 | 1 | 9 | | 5 | 1 | 1 | 7 | | 6 | 1 | 2 | 5 | | 7 | 1 | 2 | 7 | | 8 | 1 | 2 | 9 | | 9 | 1 | 3 | 1 | | 10 | 1 | 3 | 2 | | 11 | 1 | 4 | 5 | | 12 | 1 | 4 | 9 | | 13 | 1 | 5 | 7 | | 14 | 1 | 5 | 5 | | 15 | 1 | 5 | 1 | | 16 | 1 | 5 | 9 | | 17 | 1 | 8 | 7 | | 18 | 1 | 8 | 5 | | 19 | 1 | 8 | 1 | | 20 | 1 | 8 | 9 | | 21 | 1 | 8 | 6 | | 22 | 1 | 8 | 2 | | 23 | 1 | 9 | 1 | | 24 | 1 | 9 | 9 | | 25 | 2 | 2 | 1 | | 26 | 2 | 2 | 2 | | 27 | 2 | 2 | 5 | | 28 | 2 | 2 | 9 | | 29 | 2 | 2 | 7 | | 30 | 2 | 3 | 5 | | 31 | 2 | 3 | 7 | | 32 | 2 | 3 | 9 | | 33 | 2 | 4 | 1 | | 34 | 2 | 4 | 2 | | 35 | 2 | 5 | 5 | | 36 | 2 | 5 | 9 | | 37 | 2 | 6 | 7 | | 38 | 2 | 6 | 5 | | 39 | 2 | 6 | 1 | | 40 | 2 | 6 | 9 | | 41 | 2 | 9 | 7 | | 42 | 2 | 9 | 5 | | 43 | 2 | 9 | 1 | | 44 | 2 | 9 | 9 | | 45 | 2 | 9 | 6 | | 46 | 2 | 9 | 2 | | 47 | 2 | 10 | 1 | | 48 | 2 | 10 | 9 | +----+----------+------------+-----------+ 48 rows in set (0.00 sec)
###Kasus #01
> Menampilkan seluruh mahasiswa dan mata kuliah yang dia ambilnya di semester 1.
Kasus ini bisa dengan mudah kita selesaikan dengan menggunakan *INNER JOIN* dengan query seperti ini
select s.id, s.code, s.name , c.id, c.code, c.name from students s join student_courses sc on s.id=sc.student_id join courses c on sc.course_id=c.id order by s.code, s.name, c.code, c.name
![Solusi Contoh Kasus INNER JOIN Pojok Programmer](http://pojokprogrammer.net/images/tutorial/kulgram/quiz01.png)
###Kasus #02
> Menampilkan data mahasiswa yang sama sekali tidak mengambil mata kuliah di semester 1
Untuk menyelesaikan kasus seperti ini, kita harus menggunakan *LEFT OUTER JOIN* atau *LEFT JOIN*. Perhatikan bahwa table *student_courses* yang terdaftar di semester 1 hanya mahasiswa dengan id 1, 2, 3, 4, 5, 8 jadi hasil query-nya harus lah berisikan mahasiswa dengan id 6,7, dan 10.
select s.id, s.code, s.name , c.id, c.code, c.name from students s left join student_courses sc on s.id=sc.student_id and sc.semester=1 left join courses c on sc.course_id=c.id where c.code is null order by s.code, s.name, c.code, c.name
![Solusi Contoh Kasus LEFT JOIN Pojok Programmer](http://pojokprogrammer.net/images/tutorial/kulgram/quiz02.png)
###Kasus #03
> Menampilkan data mata kuliah yang tidak ada yang mengambil di semester 1.
Untuk menyelesaikan kasus seperti ini, kita bisa menggunakan *RIGHT OUTER JOIN* atau *RIGHT JOIN*. Perhatikan bahwa table *student_courses* yang mata kuliah yang diambil di semester 1 hanya mata kuliah dengan id 1, 2, 5, 6, 7, 9 jadi hasil query-nya harus lah mata kuliah dengan id 3, 4, 8, dan 10.
select s.id, s.code, s.name , c.id, c.code, c.name from students s join student_courses sc on s.id=sc.student_id and sc.semester=1 right join courses c on sc.course_id=c.id where s.code is null order by s.code, s.name, c.code, c.name
![Solusi Contoh Kasus RIGHT JOIN Pojok Programmer](http://pojokprogrammer.net/images/tutorial/kulgram/quiz03.png)
###Kasus #04
> Menampilkan daftar semua mahasiswa berikut dengan jumlah mata kuliah yang diambilnya di semester ke-2, dan menampilkan angka 0 (nol) untuk mahasiswa yang tidak mengambil mata kuliah apapun.
select s.id, s.code , s.name, count(sc.id) jumlah from students s left join student_courses sc on s.id=sc.student_id and sc.semester=2 group by s.code, s.name order by s.code, s.name
![Solusi Contoh Kasus Fungsi Aggregate dan LEFT JOIN Pojok Programmer](http://pojokprogrammer.net/images/tutorial/kulgram/quiz04.png)
###Kasus #05
> Menampilkan daftar semua mata kuliah berikut dengan jumlah mahasiswa yang mengambilnya di semester ke-2, serta menampilkan angka 0 (nol) untuk mata kuliah yang tidak diambil satupun mahasiswa.
select c.id, c.code , c.name, count(sc.id) jumlah from student_courses sc right join courses c on c.id=sc.student_id and sc.semester=2 group by c.code, c.name order by c.code, c.name
![Solusi Contoh Kasus Fungsi Aggregate dan RIGHT JOIN Pojok Programmer](http://pojokprogrammer.net/images/tutorial/kulgram/quiz05.png)
###Simpulan
Secara performa, tidak ada perbedaan performance antara *ANSI JOIN* dengan *JOIN* via *WHERE* clause. Namun keuntungan menggunakan ANSI JOIN adalah query menjadi lebih *readable* dan lebih *maintanable*, karena *JOIN condition* dan *filter condition* terpisah, gak bercampur semuanya di WHERE clause.
Ada banyak cara untuk mendapatkan hasil yang sama, misalkan dengan menggunakan *operator IN* di *klausa WHERE* untuk menjawab #Case02 dan #Case03
Kita sebagai developer harus bisa membuat query seefisien mungkin, karena bisa jadi data akan semakin banyak dan bisa jadi query yang kita buat pada saat data masih sedikit mempunyai performa buruk ketika data semakin banyak
JOIN condition tidak harus antara field yang berelasi antar table yang terlibat dengan join teresebut, namun bisa expression perbandingan dengan nilai tertentu, contohnya adalah pada *JOIN condition* di #Kasus02 #Kasus03 #Kasus04 #Case05 untuk mem-filter semester.
Jika kita menginginkan data terurut, maka pastikan kita menambahkan *ORDER BY* clause, karena di DBMS canggih seperti PostgreSQL dan Oracle, hasil yang tampilkan bisa acak jika tidak ada klausa *ORDER BY*. Hal ini dikarenakan PostgreSQL dan Oracle mampu melakukan optimasi eksekusi query secara paralel, sehingga hasil urutannya terserah optimizer DBMS bersangkutan.
Cukup sampai di sini dulu. Semoga bermanfaat.
.