LAPORAN PRAKTEK SISTEM BASIS DATA DIV TRPL Judul Praktek : Overview pembelajaran lampau (Query dan Sub Query) Nama : Dinda Tryandhary No.Bp : 1911082032 Kelas : II A Dosen Pembimbing : 1. Ibu Meri Azmi ST.,M.Cs, 2. Ibu Humaira ST.,MT PROGRAM STUDI DIV TEKNOLOGI REKAYASA PERANGKAT LUNAK JURUSAN TEKNOLOGI INFORMASI POLITEKNIK NEGERI PADANG 2020/2021 I. Tujuan praktikum Tujuan pratikum ini adalah dapat mengingat kembali tentang query dan sub query yang sudah dipelajari semester lalu sebagai dasar untuk pembelajaran pada semester ini, Mampu menyelesaikan kasus-kasus pengambilan data yang kompleks dengan pendekatan join dan subquery. II. Dasar teori A. Join Join Join Dapat Didefinisikan Sebagai KombinasiRecord Daru Dua Tabel Atau Lebih Didalam Basis Data Relasional Dan Menghasilkan Sebuah Tabel (Tempory) Baru Yang Disebut Joined Tabel. Misalkan kita akan menampilkan data yang bersumber dari fieldfield yang berasal dari tabel yang berbeda, bisa digunakan join. Struktur standar relasi tabel : select namatabel.namafield1, namatable2.namafield2 from tabel1,tabel2 where tabel1.fieldrelasi = tabel2.fieldrelasi; fieldrelasi adalah field yang merelasikan kedua tabel tersebut (atau biasa disebut foreign key) Dari soal tsb yang menjadi field relasi antara ttrans dan tpelanggan adalah kdlgn Ada beberapa tipe join yang ada di SQL : 1. Inner Join / Join 2. Left Join 3. Right Join 4. Cross Join 5. Self Join A. INNER JOIN / JOIN Inner join merupakan jenis join yang paling umum yang dapat digunakan pada semua database. Jenis ini dapat digunakan bila ingin merelasikan dua set data yang ada di tabel, letak relasinya setelah pada perintah ON pada join. Struktur dasar : Struktur 1 : select namatabel.namafield1, namatable2.namafield2 from tabel1,tabel2 where tabel1.fieldrelasi = tabel2.fieldrelasi; (struktur yang tadi) Struktur 2 : SELECT field1, field2 FROM table_1 INNER JOIN table_2 ON kondisi_join; secara lengkap dengan kondisi join : SELECT namatabel.namafield1, namatable2.namafield2 FROM tabel1 inner join tabel2 ON tabel1.fieldrelasi = tabel2.fieldrelasi; Jika kondisi_join (fieldrelasi) dari kedua tabel memiliki nama yang sama, maka struktur bisa dipersingkat menjadi : Struktur 3 : SELECT namatabel.namafield1, namatable2.namafield2 FROM tabel1 inner join tabel2 USING (fieldrelasi); Silahkan dicatat. kata- kata INNER JOIN bisa disingkat menjadi JOIN saja Sekarang contoh : Struktur 1 Struktur 2 Struktur 3 Inner join mengambil data yang beririsan dari beberapa tabel Misalkan dari 2 tabel A dan B, maka yang INNER JOIN adalah menampilkan bagian yang berwarna biru, Ada beberapa metode INNER JOIN 1. Menggunakan klausa WHERE select namatabel.namafield1, namatable2.namafield2 from tabel1,tabel2 where tabel1.fieldrelasi = tabel2.fieldrelasi; 2. Menggunakan klausa JOIN.. ON SELECT field1, field2 FROM table_1 INNER JOIN/ JOIN table_2 ON tabel1.fieldrelasi = tabel2.fieldrelasi; 3. Menggunakan klausa JOIN .. USING (khusus utk field relasi yang namanya sama) SELECT namatabel.namafield1, namatable2.namafield2 FROM tabel1 inner join tabel2 USING (fieldrelasi); Cara lain utk penyederhanaan nama tabel biasa digunakan jika join dan nama tabel terlalu panjang sehingga bisa disederhanakan Caranya dengan menjadikan alias nama tabel, seperti struktur berikut : Struktur yang awalnya sbb SELECT table1.field1, table2.field2 FROM table1 JOIN table2 ON tabel1.fieldrelasi = tabel2.fieldrelasi; disederhanakan menjadi : SELECT A.namafield1, B.namafield2 FROM tabel1 A join tabel2 B ON A.fieldrelasi = B.fieldrelasi; dengan mengubah nama table1 menjadi A dan nama table2 menjadi B B. SELF JOIN Self join adalah perintah join dimana tabel direlasikan dengan dirinya sendiri Relasi unary entitas yang memiliki relasi dengan dirinya sendiri, kalau derajat relasi unary adalah 1 to many maka entitas dengan relasi unary akan dikonversikan menjadi 1 tabel Contohnya : pada tabel employees di classicmodels Perhatikan ERD (versi crow's foot) dari classicmodels berikut : Ada relasi 1 to many yang berjenis unary (1 pada atribut reportsto dan many pada atribut employeenumber) Ini artinya bahwa pimpinan dan karyawan datanya ada pada tabel yang sama (yakni employees) dimana seorang pimpinan bisa menerima banyak laporan dari karyawan dan seorang karyawan hanya memberikan laporan pada 1 pimpinan siapa pimpinan dari karyawan dengan nomor tertentu bisa dilihat dari nilai reportsto nya , Misalkan kita ingin menampilkan nama-nama karyawan beserta nama2 managernya, maka yang ditampilkan sama-sama field nama yang ada pada tabel yang sama untuk itu kita perlu menggunakan query SELF JOIN. Struktur SELF JOIN SELECT A.namafield, B. namafield FROM tabel1 A, tabel1 B where A.fieldrelasi=B.fieldrelasi; Disini dimisalkan tabel yang sama sebagai 2 tabel yang berbeda yakni A dan B Berikut beberapa jenis outer join : -Left [Outer] Join -Left [Outer] Join without Intersection -Right [Outer] Join -Right [Outer] Join without Intersection -Full [Outer] Join -Full [Outer] Join without Intersection C. LEFT (OUTER) JOIN biasa juga disingkat dengan LEFT JOIN Left outer join (sering disingkat left join) akan mengembalikan seluruh baris dari tabel disebelah kiri yang dikenai kondisi ON dan hanya baris dari tabel disebelah kanan yang memenuhi kondisi join. Berarti kalau dengan A LEFT JOIN B, maka data yang akan ditampilkan adalah seluruh data di A baik yang berelasi dengan B maupun tidak Strukturnya : SELECT Table1.namafield1, Table2.namafield2 FROM Table1 LEFT OUTER JOIN / LEFT JOIN Table2 ON Table1.fieldrelasi = B.Table2.fieldrelasi; Contoh : Tampilkan nama barang, jumlah dan harga untuk seluruh data barang baik yang sudah terjual maupun belum select nmbrg, jml,hrg from tbrg join ttrans using(kdbrg); maka yang muncul hanyalah data irisan (inner join) jadi data yang ada pada tabel tbrg sekaligus ada pada tabel ttrans atau dengan kata lain hanya data barang yang terjual , Sementara di soal diminta seluruh data barang baik terjual maupun tidak, Jadi perintahnya kita ubah sbb : select nmbrg, jml,hrg from tbrg left outer join ttrans using(kdbrg); atau bisa disingkat select nmbrg, jml,hrg from tbrg left join ttrans using(kdbrg); D. Left [Outer] Join without Intersection Join ini merupakan variasi dari left outer join. Pada join ini kita hanya akan mengambil data dari tabel sebelah kiri yang dikenai kondisi ON yang juga memenuhi kondisi join tanpa data dari tabel sebelah kanan yang memenuhi kondisi join. Jadi kalau sebelumnya dengan Left [Outer] Join yang ditampilkan adalah seluruh isi data baik yang ada relasi maupun tidak dengan left [Outer] Join without Intersection, yang ditampilkan hanya data yang tidak memiliki relasi (tidak ada nilainya di tabel yang direlasikan) Sintaksnya : SELECT field1, field2 FROM Table1 LEFT [OUTER] JOIN Table2 ON Table1.columnName = Table2.columnName WHERE Table2.columnName IS NULL Contoh : Kalau pada contoh sebelumnya diminta tampilkan tgl, nama barang, jml dan harga utk semua barang baik yang terjual maupun tidak maka ditampilkan left[outer]join Kalau diminta tampilkan tgl, nama barang, jml dan harga utk semua barang baik yang terjual maka ditampilkan inner join (yang menghasilkan data irisan) Sementara kalau yang diminta tampilkan tgl, nama barang, jml dan harga utk semua barang baik yang tidak laku / tidak terjual --> maka ditampilkan menggunakan Left [Outer] Join without Intersection SELECT nmbrg from tbrg left join ttrans on tbrg.kdbrg=ttrans.kdbrg where ttrans.kdbrg is NULL; maka diperoleh data nama-nama barang yang tidak ada di tabel ttrans yakni barang yang tidak terjual E. RIGHT [OUTER] JOIN Right outer join (sering disingkat right join) akan mengembalikan semua baris dari tabel sebelah kanan yang dikenai kondisi ON dengan data dari tabel sebelah kiri yang memenuhi kondisi join. Teknik ini merupakan kebalikan dari left outer join. Sintaks : SELECT field1, field2 FROM Table1 RIGHT [OUTER] JOIN Table2 ON Table1.fieldrelasi = Table2.fieldrelasi ; F. RIGHT [OUTER] JOIN without Intersection Teknik ini merupakan variasi dari right outer join. Pada join ini kita hanya akan mengambil data dari tabel sebelah kanan yang dikenai kondisi ON yang juga memenuhi kondisi join tanpa data dari tabel sebelah kanan yang memenuhi kondisi join. Sintaks : SELECT field1, field2 FROM Table1 RIGHT [OUTER] JOIN Table2 ON Table1.fieldrelasi = Table2.fieldrelasi WHERE Table1.columnName IS NULL; jadi kalau left join yang diambil semua data dari tabel kiri (baik berelasi atau tidak) , sementara right join yang diambil semua data dari tabel sebelah kanan (baik berelasi atau tidak), berelasi ini artinya ada nilainya ditabel relasi Ubah contoh sebelumnya : Tampilkan nama barang, jumlah dan harga baik yang terjual maupun tidak, Kalau dijawab menggunakan left join select nmbrg, jml,hrg from tbrg left join ttrans using(kdbrg); sedangkan kalau menggunakan right join : select nmbrg, jml,hrg from ttrans right join tbrg using(kdbrg); B. Sub Query Subquery adalah perintah SELECT yang berada di dalam perintah SQL lain. Subquery sangat berguna ketika kita ingin menampilkan data dengan kondisi yang bergantung pada data di dalam table itu sendiri. Konsep dan klasifikasi penggunaan query : SUB QUERY / NESTED QUERY / QUERY didalam QUERY adalah query yang ada didalam query lainnya. Seperti SELECT, INSERT, UPDATE dan DELETE. Sub query dapat berada didalam subquery lainnya STRUKTUR : SELECT field1, field2, ..... FROM namatable WHERE field3 OPERATOR (SELECT field4 FROM namatable WHERE [kondisi]); Query pertama disebut query bagian luar Query kedua disebut query bagian dalam Operator dalam sub query bisa operator matematika, in / not in, exists / not exists, all, any, some. Contoh : Tampilkan transaksi untuk barang2 yang unitnya sama dengan barang dengan kode B001 Query dalam menghasilkan nilai satuan dari kdbrg B001 (ada sebuah nilai nantinya) Query luar menampilkan data transaksi dari barang yang satuannya sama dengan nilai yang diperoleh dari hasil query dalam Query dalamnya diapit oleh tanda kurung SELECT satuan tgl,nonota, kdbrg,jml,hrg FROM ttrans JOIN tbrg using(kdbrg) Query Luar (SELECT unit FROM tbrg WHERE kdbrg='B001'); query dalam SELECT tgl,nonota, kdbrg,jml,hrg FROM ttrans JOIN tbrg using(kdbrg) WHERE satuan = (SELECT satuan FROM tbrg WHERE kdbrg='B001'); Soal : Tampilkan transaksi untuk barang2 yang unitnya sama dengan barang dengan kode B001 Kalau tanpa sub query, kita lakukan dengan 2 langkah langkah 1 : SELECT satuan FROM tbrg WHERE kdbrg='B001'; dapat hasil : Unit langkah 2 : SELECT tgl,nonota, kdbrg,jml,hrg FROM ttrans JOIN tbrg using(kdbrg) WHERE satuan = 'unit'; nilai unit diperoleh dari hasil langkah 1 Disoal tdk diminta tampilkan data transaksi yang satuannya unit. Satuan unit baru kita peroleh setelah melakukan langkah 1, Nah dengan subquery langkah 1 bisa digabung dengan langkah 2, dimana nilai unit pada langkah 2 digantikan dengan query langkah 1 sehingga perintah menjadi : SELECT tgl,nonota, kdbrg,jml,hrg FROM ttrans JOIN tbrg using(kdbrg) WHERE satuan = (SELECT satuan FROM tbrg WHERE kdbrg='B001'); SELECT field1, field2, ..... FROM namatable WHERE field3 OPERATOR (SELECT field4 FROM namatable WHERE [kondisi]); disitu ada OPERATOR sama dengan (=) 1. SUB QUERY DALAM KLAUSA WHERE A. Sub Query dengan operator perbandingan Kita dapat menggunakan operator pembanding misal: =, !=, >=, >, <, <= Operator ini digunakan untuk membandingkan nilai tunggal yang dikembalikan oleh subquery dengan ekspresi dalam klausa WHERE. contohnya soal tadi nilai dari query dalam menghasilkan nilai tunggal yakni nilai unit. Makanya bisa kita gunakan operator perbandingan, Jadi Operator perbandingan bisa digunakan jika nilai yang dikembalikan adalah tunggal. B. Sub Query dengan operator IN dan NOT IN Jika subquery mengembalikan lebih dari satu nilai, kita dapat menggunakan operator lain seperti operator IN atau NOT IN dalam klausa WHERE. Contoh l : Tampilkan data pelanggan yang tidak membeli apapun pada tabel ttrans. Query ini akan menampilkan yang lebih dari satu, karena ada banyak pelanggan belum pernah membeli barang apapun. Soal ini bisa kita selesaikan menggunakan LEFT / RIGHT JOIN juga menggunakan LEFT JOIN : SELECT tpelanggan.kdlgn, nmlgn FROM tpelanggan LEFT JOIN ttrans USING(kdlgn) WHERE ttrans.kdlgn IS NULL; menggunakan RIGHT JOIN SELECT tpelanggan.kdlgn, nmlgn FROM ttrans RIGHT JOIN tpelanggan USING(kdlgn) WHERE ttrans.kdlgn IS NULL; menggunakan sub query : SELECT kdlgn, nmlgn FROM tpelanggan WHERE kdlgn NOT IN (SELECT kdlgn from ttrans); 2. SUB QUERY didalam klausa FROM Saat menggunakan subquery dalam klausa FROM, hasil yang kembali dari subquery digunakan sebagai tabel sementara. Struktur : SELECT field1, field2, .... FROM (SELECT field_a, field_b FROM namatabel) AS nama_query WHERE [kondisi]; 3. SUB QUERY dengan EXISTS dan NOT EXISTS Ketika subquery digunakan dengan operator EXISTS atau NOT EXISTS, subquery mengembalikan nilai Boolean dari TRUE atau FALSE. Struktur : SELECT EXISTS (SELECT field1, field2, ... FROM table_name WHERE [kondisi]); 4. Sub Query dengan ANY, SOME, ALL Query ANY dan SOME dipakai untuk membandingkan salah satu data himpunan subquery. Sedangkan query ALL akan membandingkan seluruh data yang ada dihimpunan subquery. III. Langkah kerja 1. Pertama buka aplikasi XAMPP 2. Klik start pada mysql 3. Lalu ketik mysql -u root IV. Tugas dan penjelasan Jawablah soal-soal dibawah ini, gunakan database classicmodels : SOAL QUERY : 1. Tampilkan nama lengkap karyawan, jobtitle, country, state dengan ketentuan CA= CAlifornia, NY=New York, MA = Massachusetts, kalau ada selain itu buat other untuk karyawan yang berada di negara USA. select concat(firstname,lastname), employees.jobtitle, offices.country, case offices.state when 'CA' then 'california' when 'NY' then 'new york' when 'MA' then 'massachusetts' else 'order' end as state from employees, offices where employees.officecode = offices.officecode and country = 'USA'; => Fungsi concat digunakan untuk menyambungkan dua atau lebih string 2. Tampilkan nama customer, orderdate, lama waktu tunggu yang dibutuhkan dari waktu pengiriman (shippeddate) hingga waktu pemesanan dari table order (orderdate). untuk barang yg diorder pada Januari - Agustus 2004 dan masa tunggu diatas 5 hari, urutkan dari waktu tunggu terpendek. select customerName, orderDate, dateDiff(shippedDate,orderDate) as waktuTunggu from customers join orders using(customerNumber) where orderDate between '2004-01-01' and '2004-08-31' and dateDiff(shippedDate,orderDate) > 5 order by WaktuTunggu; => Penggunaan datediff untuk selisih waktu pemesanan dan waktu tunggu,orderdate untuk mengurutkan tanggal 3. Tampilkan nama kontak customer lengkap dengan huruf kapital, alamat lengkap (addressline1 + state), creditlimit dan nama product yang dibeli oleh customer tersebut, untuk pelanggan yang berada di state MA,MY, NV, CA dan NJ dan credit limit antara 50.000 – 100.000, hanya untuk productname adalah Harley Urutkan dari creditlimit tertinggi Select ucase(concat(contactFirstname,' ',contactLastname)) fullname, concat(addressline1,' ',state)fulladdress, creditlimit,productName,state from customers join orders using(customerNumber) join orderdetails using(OrderNumber) join products using(productCode) where state in("MA","MY","NV","CA","NJ") and creditLimit between 50000 and 100000 and productName like "%Harley%" order by creditLimit desc; => From customers join orders using(cunstomerNUmber) join orderDetails using(orderNumber) join product using (productCode) (penggunaan using hanya utk field relasi yang namanya sama ), karena antara tabel customers dengan orders berelasi di customernumber, tabel orders dengan orderdetails berelasi pada ordernumber dan orderdetails dengan products berelasi pada productcode. Jadi, karena field relasi antara 2 tabel berelasi sama bisa digunakan join.. using 4. Tampilkan nama pelanggan, kontak lengkap pelanggan yang membeli barang dengan nama harley select customerName as 'nama pelanggan', concat(contactFirstName,' ',contactLastName) as 'kontak lengkap', productName from customers, orders, orderdetails, products where customers.customerNumber = orders.customerNumber and orders.orderNumber = orderdetails.orderNumber and orderdetails.productCode = products.productCode and productName like '%harley%'; => ada 4 tabel yg masing2 terhubung 5. Tampilkan nama lengkap employee, di city mana employee tsb ditempatkan. Untuk state yang memiliki nilai null, ganti dengan nilai country. select concat(firstname,' ',lastname) as nama_lengkap, offices.city, ifnull(offices.state,offices.country) as state from employees, offices where employees.officecode = offices.officecode; 6. Nama product apa saja yang sudah dijual oleh employee yang bernama Leslie Thompson dan siapa nama customer yg membeli product tersebut. Tampilkan hanya untuk product yang dikirim (shippeddate) pada tahun 2003 select concat(firstname,' ',lastname)name, productname, customername, shippeddate from employees join customers on employees.employeenumber=customers.salesrepemployeenumber join orders using(customernumber) join orderdetails using(ordernumber) join products using(productcode) where concat(firstname,' ',lastname)='Leslie Thompson' and year(shippeddate)=2003; => employees dan customers memiliki penamaan field yg berberda , menggukan perintah join lalu gabung antara join on untuk field relasi yg namanya tidak sama dan join using untuk field relasi yg sma 7. Tampilkan semua data dari tabel payments tetapi hanya untuk pelanggan dengan customernumber = 124, untuk payments yang terjadi pada tahun 2004 saja dan amount diatas 50000. Tampilkan customername, paymentdate dengan format tanggal, nama bulan dan tahun. select payments.* , customers .customerName from customers, payments where payments.customerNumber = 124 and year(payments.paymentdate) = 2004 and payments.amount >= 50000 and payments.customerNumber = customers.customerNumber; 8. Jika profit didapatkan dari selisih harga jual dan harga beli, maka keuntungan tiap2 barang adalah selisih harga dikalian dengan quantityorder. berapa kira-kira kerugian yang didapatkan oleh perusahaan untuk barang yang tidak jadi dibeli(cancelled). Select productname, quantityinstock, priceeach,buyprice, (priceeach buyprice) as 'harga jual', round((priceeach-buyprice)*quantityordered) as kerugian from orderdetails, products, orders where products.productcode = orderdetails.productcode and orderdetails.ordernumber = orders.ordernumber and orders.status = 'cancelled'; 9. Tampilkan tanggal order, nama produk (huruf kapital), quantityorder, price each, total (quantity * price) untuk produk berjenis classic cars yang diorder selama januari juni 2003, yang ordernya antara 50-100. Tampilkan 10 data saja untuk total harga tertinggi dan total ditampilkan pembulatan dengan 2 angka dibelakang koma Select orderdate, upper(productname), quantityordered, priceeach, format((quantityordered * priceeach),2) as total from products, orderdetails, orders where products.productcode = orderdetails.productcode and orderdetails.ordernumber = orders.ordernumber and products.productline = 'classic cars' and orders.orderdate between '2003-01-01' and '2003-06-31' and orderdetails.quantityordered between '50' and '100' limit 10; 10. Tampilkan nama lengkap karyawan, nama customer yang dilayani, alamat yang diambil dari addressline2 (jika tidak ada addressline2 (nilainya NULL), ganti dengan addressline1, country dan creditlimit untuk pelanggan yang country nya USA dan kreditlimitnya antara 50000 dan 75000. Urutkan dari kreditlimit tertinggi Select concat(firstname,lastname) as 'nama lengkap', customername, ifnull(customers.addressline2,customers.addressline1), customers.country, creditlimit from employees, customers where employees.employeenumber = customers.salesrepemployeenumber and customers.country = 'USA' and creditlimit between 50000 and 75000 order by creditlimit desc; SOAL SUB QUERY : 1. Tampilkan nama lengkap employee yang sama-sama bekerja (satu office) dengan employee yang bernama Peter Marsh select concat(firstName,lastName)as nama_lengkap, officeCode from employees where officeCode in (select officeCode from employees Where concat(firstName,lastName) regexp `PeterMarsh`); 2. Tampilkan nama lengkap employee, manager untuk employee yang memiliki manager yang sama dengan Mary Patterson select concat(e.firstName," ",e.lastName) NamaLengkapKaryawan,concat(m.firstName," ",m.lastName) NamaLengkapManager from employees e join employees m on e.reportsTo = m.employeeNumber where concat(m.firstName," ",m.lastName)= (select concat(m.firstName,' ',m.lastName) manajerNam from employees m, employees k where k.reportsto=m.employeeNumber and concat(k.firstName,' ',k.lastName) ='Mary Patterson'); => menggunakan self join 3. Tampilkan nama customer yang membeli product yang sama dengan customer yang bernama Toys, tampilkan 25 data saja. select customerName,productName from customers join orders using (customerNumber) join orderDetails using (orderNumber) join products using (productCode) where productName in(select productName from customers join orders using (customerNumber) join orderDetails using (orderNumber) join products using (productCode) where customerName like “%Toys%”) limit 25; 4. Tampilkan siapa saja customer yg memiliki status order yang sama dengan customer yang bernama scandinavian select customerName, status from customers join orders using(customerNumber) where status in(select status from orders join customers using(customerNumber) where customerName like %Scandinavian%); 5. Siapakah nama customer yang melakukan pembayaran diatas pembayaran rata-rata ditahun 2004? Tampilkan nama customer, paymentdate dan amount. select customerName,paymentDate,amount from customers join payments using(customerNumber) where amount > (select avg(amount) from payments where year(paymentDate)=”2004”); 6. Tampilkan jumlah product paling banyak, paling sedikit dan rata2 barang yang dibeli berdasarkan nama customer. select max(item) ProdukPalingBanyak,min(item) ProdukPalingSedikit,avg(item) Rata2 from (select count(*) as item from customers join orders using(customerNumber) join orderDetails using(orderNumber) join products using(productCode) group by customerName) as query1; => menggunakan query dalam, hitung banyak produk lalu kelompokkan berdasarkan customername , banya produk tersebut akan menjadu dasar untuk max,min dan avg 7. Adakah pelanggan yang membeli product dengan nama The Titanic? Titanic? Select if(exists(select customerName From customers join orders using (customerNumber) Join orderDetails using(orderNumber) Join products using (productCode) Where productName like'%titanic%') , 'ada', 'tidak ada') as nama; 8. Tampilkan tanggal order, nama customers, nama produk yang dibeli, country dan status untuk produk yang namanya ford dan customers yang tinggal di negara yang sama dengan customernumber 282 dan 496 dan statusnya selain 'shipped'. Urutkan berdasarkan tanggal order terkini. select orderDate, customerName, productName, country, status from customers join orders using(customerNumber) join orderdetails using(orderNumber) join products using(productCode) where productName like '% Ford%' and country in (select country from customers where customerNumber in (282,496)) and status != 'Shipped' order by orderDate; V. Kesimpulan Sub Query adalah query nested atau sebuah query yang berada di dalam query. Sub query bisa digunakan untuk select, update, delete, dsb. Indeks digunakan untuk mempercepat pengaksesan data, karena indeks akan mempermudah pencarian data saat query dijalankan, dan kita harus memperhatikan logika soal karena jika salah memasukkan perintah kita akan keliru terhadap hasilnya nanti. VI. Referensi http://catatankuliahum.blogspot.com/2013/02/sub-query-basis-data.html https://aandev.blogspot.com/2017/02/pengertian-dan-macam-macam-join-dalam.html Laporan praktek database semester II