Tujuan

Subquery adalah query yang hasilnya diteruskan sebagai argumen untuk permintaan lain. Subqueries memungkinkan Anda untuk beberapa pertanyaan mengikat. Pada akhir hari, Anda akan memahami dan dapat melakukan hal berikut:

  • Membangun sebuah subquery
  • Gunakan kata kunci yang ada, APAPUN, dan SEMUA dengan subqueries Anda
  • Membangun dan menggunakan subqueries berkorelasi

CATATAN: Contoh untuk pelajaran hari ini diciptakan dengan menggunakan Borland ISQL, pelaksanaan yang sama yang digunakan pada Hari 6, “Bergabung dengan Tabel.” Ingat, implementasi ini tidak menggunakan SQL> prompt atau nomor baris.


Membangun sebuah Subquery

Sederhananya, subquery memungkinkan Anda dasi hasil satu set query yang lain. Sintaks umum adalah sebagai berikut:

Sintaks:
  SELECT * 
  DARI TABLE1 
  WHERE TABLE1.SOMECOLUMN = 
  (SELECT SOMEOTHERCOLUMN 
  DARI TABLE2 
  WHERE SOMEOTHERCOLUMN = SOMEVALUE) 

Perhatikan bagaimana permintaan kedua adalah bersarang di dalam pertama. Berikut adalah contoh nyata dunia yang menggunakan tabel BAGIAN dan Pesanan:

INPUT:
  SELECT * 
  BAGIAN DARI
OUTPUT:
  PARTNUM URAIAN HARGA 
  =========== ==================== =========== 

           54 pedal 54,25 
           42 Kursi 24,50 
           46 Ban 15,25 
           23 SEPEDA GUNUNG 350,45 
           76 JALAN SEPEDA 530,00 
           10 Tandem 1.200,00
INPUT / OUTPUT:
 SELECT * FROM ORDEREDON NAMA PARTNUM KOMENTAR kuantitas pesanan =========== ========== =========== ========= == ======== 15-MAY-1996 WHEEL TRUE 23 6 DIBAYAR 19-MUNGKIN-WHEEL TRUE 1.996 76 3 DIBAYAR 2-September-1996 WHEEL TRUE 10 1 DIBAYAR 30-Juni-1996 WHEEL TRUE 42 8 DISETOR 30-JUN-1996 SEPEDA SPEC 54 10 DIBAYAR 30-MUNGKIN-1996 SEPEDA SPEC 10 2 DIBAYAR 30-MUNGKIN-1996 SEPEDA SPEC 23 8 DIBAYAR 17-JAN-1996 SEPEDA SPEC 76 11 DIBAYAR 17-JAN-1996 LE Shoppe 76 5 DISETOR 1-JUN-1996 LE Shoppe 10 3 DIBAYAR 1-Juni 1996 AAA SEPEDA-10 1 DIBAYAR 1-Juli-1996 SEPEDA AAA 76 4 DIBAYAR 1-Juli-1996 SEPEDA AAA 46 14 DIBAYAR 11-Juli-1996 SEPEDA Jacks 76 14 DISETOR
ANALISIS:

Tabel berbagi bidang umum yang disebut PARTNUM. Misalkan Anda tidak tahu (atau tidak mau tahu) yang PARTNUM, tapi ingin bekerja dengan gambaran bagian. Menggunakan subquery, Anda bisa mengetik ini:

INPUT / OUTPUT:
 SELECT * FROM Orders WHERE PARTNUM = SELECT PARTNUM (BAGIAN MANA DARI URAIAN SEPERTI "% JALAN") ORDEREDON PARTNUM KUANTITAS NAMA =========== ========== ==== KOMENTAR ======= =========== ======== 19-MAY-1996 WHEEL TRUE 76 3 DIBAYAR 17-JAN-1996 SEPEDA SPEC 76 11 DIBAYAR 17-JAN- 1996 LE Shoppe 76 5 DIBAYAR 1-Juli-1996 AAA SEPEDA 76 4 DIBAYAR 11-Juli-1996 SEPEDA Jacks 76 14 DISETOR
ANALISIS:

Bahkan lebih baik, jika Anda menggunakan konsep yang Anda pelajari pada Hari 6, Anda dapat meningkatkan kolom PARTNUM dalam hasilnya dengan termasuk URAIAN, membuat PARTNUM jelas bagi siapa saja yang belum hafal itu. Coba ini:

INPUT / OUTPUT:
  SELECT O. ORDEREDON, O. PARTNUM, 
  URAIAN P., O. KUANTITAS, O. KOMENTAR 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 
  DAN 
  O. PARTNUM = 
  (SELECT PARTNUM 
  BAGIAN DARI 
  URAIAN SEPERTI MANA "% JALAN") 

    ORDEREDON PARTNUM KUANTITAS URAIAN KOMENTAR 
  =========== =========== ============ =========== ===== ==== 

  19-MAY-1996 76 SEPEDA JALAN 3 DISETOR 
   1-JUL-1996 76 SEPEDA JALAN 4 DISETOR 
  17-JAN-1996 76 JALAN SEPEDA 5 DISETOR 
  17-JAN-1996 76 11 SEPEDA JALAN DIBAYAR 
  11-JUL-1996 76 14 SEPEDA JALAN DIBAYAR 
ANALISIS:

Bagian pertama dari query sangat akrab:

  SELECT O. ORDEREDON, O. PARTNUM, 
  URAIAN P., O. KUANTITAS, O. KOMENTAR 
  DARI O pesanan, P BAGIAN 

Di sini Anda menggunakan alias O dan P untuk perintah tabel dan BAGIAN untuk memilih lima kolom Anda tertarik Dalam hal ini alias tidak diperlukan karena masing-masing kolom Anda diminta untuk kembali adalah unik. Namun, lebih mudah untuk membuat permintaan dibaca sekarang daripada harus mencari tahu nanti. WHERE klausa pertama yang Anda hadapi

  PARTNUM WHERE O. = P. PARTNUM 

adalah bahasa standar untuk bergabung tabel BAGIAN dan perintah yang ditetapkan dalam klausa FROM. Jika Anda tidak menggunakan klausa WHERE, Anda akan memiliki semua kombinasi baris kemungkinan dua meja. Bagian berikutnya berisi subquery itu. Pernyataan

  DAN 
  O. PARTNUM = 
  (SELECT PARTNUM 
  BAGIAN DARI 
  URAIAN SEPERTI MANA "% JALAN") 

Menambahkan O. PARTNUM kualifikasi yang harus sama dengan hasil dari subquery sederhana Anda. subquery adalah langsung, mencari semua nomor bagian yang SEPERTI "% JALAN".Penggunaan SEPERTI agak malas, tabungan Anda penekanan tombol yang dibutuhkan untuk jenis JALAN SEPEDA. Namun, ternyata Anda beruntung kali ini. Bagaimana jika seseorang di departemen Bagian telah menambahkan bagian baru yang disebut roadkill? Tabel BAGIAN revisi akan terlihat seperti ini:

INPUT / OUTPUT:
  SELECT * 
  BAGIAN DARI 

      PARTNUM URAIAN HARGA 
  =========== ==================== =========== 

           54 pedal 54,25 
           42 Kursi 24,50 
           46 Ban 15,25 
           23 SEPEDA GUNUNG 350,45 
           76 JALAN SEPEDA 530,00 
           10 Tandem 1.200,00 
           77 roadkill 7,99 

Misalkan Anda tidak menyadari perubahan ini dan coba query Anda setelah ini produk baru telah ditambahkan. Jika Anda memasukkan ini:

  SELECT O. ORDEREDON, O. PARTNUM, 
  URAIAN P., O. KUANTITAS, O. KOMENTAR 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 
  DAN 
  O. PARTNUM = 
  (SELECT PARTNUM 
  BAGIAN DARI 
  URAIAN SEPERTI MANA "% JALAN") 

mesin SQL mengeluh

  beberapa baris di pilih tunggal 

dan Anda tidak mendapatkan hasil apapun. Tanggapan dari mesin SQL Anda dapat berbeda, tetapi masih mengeluh dan kembali apa-apa. Untuk mengetahui mengapa Anda mendapatkan hasil yang tidak diinginkan, berperan sebagai mesin SQL. Anda mungkin akan mengevaluasi subquery yang pertama. Anda akan kembali ini:

INPUT / OUTPUT:
  SELECT PARTNUM 
  BAGIAN DARI 
  URAIAN SEPERTI MANA "% JALAN" 

      PARTNUM 
  =========== 

           76 
           77 

Anda akan mengambil hasil ini dan menerapkannya ke O. PARTNUM =, yang merupakan langkah yang menyebabkan masalah.

ANALISIS:

Bagaimana PARTNUM sama dengan baik 76 dan 77? Ini harus apa mesin maksudkan ketika itu menuduh Anda sebagai orang tolol. Bila Anda menggunakan klausa LIKE, Anda membuka diri untuk kesalahan ini. Ketika Anda menggabungkan hasil operator relasional dengan operator lainnya relasional, seperti =, <, atau>, Anda harus memastikan hasilnya adalah tunggal. Dalam kasus contoh kita telah menggunakan, solusi akan menulis ulang query menggunakan = bukan SEPERTI, seperti ini:

INPUT / OUTPUT:
 SELECT O. ORDEREDON, O. PARTNUM, P. URAIAN, O. KUANTITAS, O. KOMENTAR dari pesanan O, BAGIAN MANA PARTNUM O. P = P. PARTNUM DAN PARTNUM O. = (PARTNUM SELECT FROM WHERE BAGIAN URAIAN = "JALAN SEPEDA ) ORDEREDON PARTNUM KUANTITAS URAIAN KOMENTAR =========== =========== =============== ====== ===== ========== 19-MAY-1996 76 JALAN SEPEDA 3 DIBAYAR 1-Juli-1996 76 JALAN SEPEDA 4 DIBAYAR 17-JAN-1996 76 JALAN SEPEDA 5 DIBAYAR 17-JAN-1996 76 JALAN SEPEDA 11 DIBAYAR 11-Juli-1996 76 14 SEPEDA JALAN DIBAYAR
ANALISIS:

subquery ini hanya mengembalikan satu hasil yang unik, sehingga mempersempit = kondisi Anda ke nilai tunggal. Bagaimana Anda bisa yakin subquery tidak akan kembali beberapa nilai jika Anda mencari hanya satu nilai?

Menghindari penggunaan SEPERTI adalah memulai. Pendekatan lain adalah untuk memastikan keunikan kolom pencarian pada desain meja. Jika Anda adalah tipe untrusting, Anda bisa menggunakan metode (dijelaskan kemarin) untuk bergabung dengan meja untuk dirinya sendiri untuk memeriksa suatu bidang tertentu untuk keunikan. Jika Anda desain tabel sendiri (lihat Hari 9, “Menciptakan dan Mempertahankan Tabel”) atau percaya kepada orang yang merancang meja, Anda dapat memerlukan kolom yang Anda cari untuk memiliki nilai yang unik. Anda juga bisa menggunakan bagian dari SQL yang mengembalikan hanya satu jawaban: fungsi agregat.

Menggunakan Fungsi Agregat dengan Subqueries

Keseluruhan fungsi SUM, COUNT, MIN, MAX, dan AVG semua mengembalikan nilai tunggal. Untuk menemukan jumlah rata-rata pesanan, jenis ini:

INPUT:
  SELECT AVG (O. KUANTITAS * P. HARGA) 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM
OUTPUT:
 
  AVG 
  =========== 

      2.419,16 
ANALISIS:

Pernyataan ini mengembalikan hanya satu nilai. Untuk mengetahui yang berada di atas rata-rata perintah, gunakan perintah SELECT untuk subquery Anda sebelumnya. Permintaan lengkap dan hasil adalah sebagai berikut:

INPUT / OUTPUT:
  SELECT NAMA O. O., ORDEREDON, 
  KUANTITAS O. * P. HARGA TOTAL 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 
  DAN 
  KUANTITAS O. * P. HARGA> 
  (SELECT AVG (O. KUANTITAS * P. HARGA) 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM) 

  NAMA ORDEREDON TOTAL 
  ========== =========== =========== 

  LE Shoppe 1-JUN-1996 3600,00 
  SEPEDA SPEC 30-MAY-1996 2.803,60 
  LE Shoppe 17-JAN-1996 2650,00 
  SEPEDA SPEC 17-JAN-1996 5830,00 
  Jacks SEPEDA 11-JUL-1996 7420,00 
ANALISIS:

Contoh ini berisi SELECT biasa-biasa saja agak / FROM / klausa WHERE:

  SELECT NAMA O. O., ORDEREDON, 
  KUANTITAS O. * P. HARGA TOTAL 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 

Garis-garis ini merupakan cara yang umum untuk bergabung dengan kedua tabel. Bergabung ini diperlukan karena harga di BAGIAN dan kuantitas yang di perintah.. Para MANA memastikan bahwa Anda hanya memeriksa bergabung membentuk-baris yang berhubungan dengan Anda kemudian menambahkan subquery ini:

 KUANTITAS DAN HARGA O. * P.> (SELECT AVG (KUANTITAS O. * P. HARGA) dari pesanan O, P BAGIAN MANA PARTNUM O. = P. PARTNUM)

Kondisi sebelumnya membandingkan total setiap pesanan dengan rata-rata yang dihitung dalam subquery itu. Perhatikan bahwa bergabung dalam subquery diwajibkan untuk alasan yang sama seperti dalam laporan SELECT utama. Bergabung ini juga dibangun persis dengan cara yang sama. Ada rahasia jabat tangan di subqueries; mereka sintaks yang sama persis sebagai permintaan mandiri. Bahkan, kebanyakan subqueries dimulai sebagai pertanyaan mandiri dan digabungkan sebagai subqueries setelah hasil mereka diuji.

Bersarang Subqueries

Bersarang adalah tindakan embedding subquery di dalam subquery yang lain. Sebagai contoh:

  Pilih * DARI SESUATU WHERE (SUBQUERY (SUBQUERY (SUBQUERY))); 

Subqueries dapat diulang sedalam implementasi dari SQL memungkinkan Anda. Misalnya, untuk mengirim pemberitahuan spesial untuk pelanggan yang menghabiskan lebih dari jumlah rata-rata uang, Anda akan menggabungkan informasi dalam tabel PELANGGAN

INPUT:
  SELECT * 
  DARI PELANGGAN
OUTPUT:
  
  ALAMAT NAMA NEGARA ZIP PHONE KOMENTAR 
  ========== ========== ====== ========== =========== === ======= 

  WHEEL TRUE 55O HUSKER NE 58.702 555-4.545 NONE 
  SEPEDA SPEC CPT mendengarkan pengakuan dosa dan LA 45678 555-1234 NONE 
  LE KS Hometown Shoppe 54678 555-1278 NONE 
  SEPEDA AAA 10 OLDTOWN NE 56.784 555-3.421 JOHN-Mgr 
  Jacks SEPEDA 24 Eglin FL 34.567 555-2.314 NONE 

dengan versi yang dimodifikasi sedikit dari query yang digunakan untuk menemukan perintah di atas rata-rata:

INPUT / OUTPUT:
  PILIH SEMUA NAMA C., C. ALAMAT, C. NEGARA, C. ZIP 
  DARI PELANGGAN C 
  C. NAMA DI MANA 
  (SELECT NAMA O. 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 
  DAN 
  KUANTITAS O. * P. HARGA> 
  (SELECT AVG (O. KUANTITAS * P. HARGA) 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM)) 

  ALAMAT NAMA NEGARA ZIP 
  ========== ========== ====== ========== 

  SEPEDA SPEC CPT 45.678 mendengarkan pengakuan dosa dan LA 
  Hometown Shoppe LE KS 54678 
  Jacks SEPEDA 24 Eglin FL 34567 
ANALISIS:

Berikut adalah melihat apa yang Anda minta. Di paling set tanda kurung, Anda akan menemukan pernyataan akrab:

  SELECT AVG (O. KUANTITAS * P. HARGA) 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 

Hasil ini feed ke versi yang dimodifikasi sedikit dari klausa SELECT yang Anda gunakan sebelumnya:

 O. SELECT NAMA dari pesanan O, BAGIAN MANA PARTNUM O. P = P. PARTNUM DAN KUANTITAS O. * P. HARGA> (...)

Catatan klausa SELECT telah dimodifikasi untuk kembali satu kolom, NAMA, yang tidak begitu kebetulan, adalah sama dengan tabel PELANGGAN. Menjalankan laporan ini dengan sendirinya Anda mendapatkan:

INPUT / OUTPUT:
  O. SELECT NAME 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM 
  DAN 
  KUANTITAS O. * P. HARGA> 
  (SELECT AVG (O. KUANTITAS * P. HARGA) 
  DARI O pesanan, P BAGIAN 
  PARTNUM WHERE O. = P. PARTNUM) 

  NAMA 
  ========== 

  LE Shoppe 
  SEPEDA SPEC 
  LE Shoppe 
  SEPEDA SPEC 
  Jacks SEPEDA 
ANALISIS:

Kami hanya menghabiskan waktu beberapa mendiskusikan mengapa subqueries Anda harus mengembalikan hanya satu nilai. Alasannya permintaan ini dapat kembali lebih dari satu nilai menjadi jelas dalam sekejap.

Anda membawa hasil ini dengan pernyataan:

  C. SELECT NAMA, ALAMAT C., C. NEGARA, C. ZIP 
  DARI PELANGGAN C 
  C. NAMA DI MANA 

  (...) 
ANALISIS:

Dua baris pertama adalah biasa-biasa saja. Yang ketiga perkenalkan kembali kata kunci DALAM, terakhir terlihat pada Hari 2, “Pengantar Query: SELECT Pernyataan DI." Adalah alat yang memungkinkan Anda untuk menggunakan beberapa baris output dari subquery Anda. DI, seperti yang Anda ingat, mencari pertandingan berikut seperangkat nilai-nilai yang tertutup oleh tanda kurung, yang dalam hal ini menghasilkan nilai berikut:

  LE Shoppe 
  SEPEDA SPEC 
  LE Shoppe 
  SEPEDA SPEC 
  Jacks SEPEDA 

subquery ini menyediakan kondisi yang memberi Anda mailing list:

  ALAMAT NAMA NEGARA ZIP 
  ========== ========== ====== ====== 

  SEPEDA SPEC CPT mendengarkan pengakuan dosa dan LA 45678 
  Hometown Shoppe LE KS 54678 
  Jacks SEPEDA 24 Eglin FL 34567 

DI ini menggunakan sangat umum di subqueries. Karena DI menggunakan seperangkat nilai untuk perbandingan, ia tidak menyebabkan mesin SQL merasa berkonflik dan tidak memadai.

Subqueries juga dapat digunakan dengan klausa GROUP BY dan HAVING tersebut. Periksa query berikut:

INPUT / OUTPUT:
  SELECT NAMA, AVG (KUANTITAS) 
  Dari pesanan 
  GROUP BY NAME 
  HAVING AVG (KUANTITAS)> 
  (SELECT AVG (KUANTITAS) 
  Dari pesanan) 

  NAMA AVG 
  ========== =========== 

  SEPEDA 8 SPEC 
  Jacks SEPEDA 14 
ANALISIS:

Mari kita memeriksa permintaan ini dalam urutan mesin SQL akan. Pertama, lihatlah subquery ini:

INPUT / OUTPUT:
  SELECT AVG (KUANTITAS) 
  Dari pesanan 

          AVG 
  =========== 

            6 

Dengan sendirinya, pertanyaan adalah sebagai berikut:

INPUT / OUTPUT:
 SELECT NAMA, AVG (KUANTITAS) dari pesanan NAMA NAMA GROUP BY AVG =========== ========== AAA 6 SEPEDA SEPEDA SEPEDA SPEC 8 jack 14 LE Shoppe 4 WHEEL TRUE 5

Ketika dikombinasikan melalui klausa HAVING, subquery menghasilkan dua baris yang memiliki rata-rata di atas KUANTITAS.

INPUT / OUTPUT:
  HAVING AVG (KUANTITAS)> 
  (SELECT AVG (KUANTITAS) 
  Dari pesanan) 

  NAMA AVG 
  =========== ========== 

  SEPEDA 8 SPEC 
  Jacks SEPEDA 14 

Berkorelasi Subqueries

Para subqueries Anda tulis sejauh ini mandiri. Tak satu pun dari mereka telah menggunakan referensi dari luar subquery yang subqueries. Terkorelasi memungkinkan Anda untuk menggunakan referensi di luar dengan beberapa hasil yang aneh dan indah. Lihat pertanyaan berikut:

INPUT:
  SELECT * 
  DARI O Pesanan 
  WHERE 'JALAN SEPEDA' = 
  (SELECT URAIAN 
  BAGIAN DARI P 
  WHERE PARTNUM P. = O. PARTNUM)
OUTPUT:
  NAMA ORDEREDON KUANTITAS PARTNUM KOMENTAR 
  =========== ========== =========== =========== ======= === 

  19-MAY-1996 WHEEL TRUE 76 3 DISETOR 
  17-JAN-1996 SEPEDA SPEC 76 11 DISETOR 
  17-JAN-1996 LE Shoppe 76 5 DISETOR 
   1-JUL-1996 SEPEDA AAA 76 4 DISETOR 

  11-JUL-1996 jack SEPEDA 76 14 DISETOR 

Query ini benar-benar menyerupai JOIN berikut:

INPUT:
  SELECT O. ORDEREDON, O. NAMA, 
  O. PARTNUM, O. KUANTITAS, O. KOMENTAR 
  DARI O pesanan, P BAGIAN 
  WHERE PARTNUM P. = O. PARTNUM 
  DAN '= JALAN SEPEDA URAIAN P.'
OUTPUT:
  NAMA ORDEREDON KUANTITAS PARTNUM KOMENTAR 
  =========== ========== =========== =========== ======= 

  19-MAY-1996 WHEEL TRUE 76 3 DISETOR 
   1-JUL-1996 SEPEDA AAA 76 4 DISETOR 
  17-JAN-1996 LE Shoppe 76 5 DISETOR 
  17-JAN-1996 SEPEDA SPEC 76 11 DISETOR 
  11-JUL-1996 jack SEPEDA 76 14 DISETOR 
ANALISIS:

Pada kenyataannya, kecuali perintah itu, hasilnya identik. The subquery berkorelasi bertindak sangat mirip dengan bergabung. korelasi dibentuk dengan menggunakan elemen dari query di subquery itu. Dalam contoh ini korelasi didirikan oleh pernyataan

  WHERE PARTNUM P. = O. PARTNUM 

di mana Anda membandingkan P. PARTNUM, dari tabel di dalam subquery Anda, untuk O. PARTNUM, dari meja luar query Anda. Karena O. PARTNUM dapat memiliki nilai yang berbeda untuk setiap baris, yang berkorelasi subquery dijalankan untuk setiap baris dalam query. Pada contoh berikut ini setiap baris dalam tabel Perintah

INPUT / OUTPUT:
  SELECT * 
  Dari pesanan 

    NAMA ORDEREDON KUANTITAS PARTNUM KOMENTAR 
  =========== ========== =========== =========== ======= 

  15-MAY-1996 WHEEL TRUE 23 6 DISETOR 
  19-MAY-1996 WHEEL TRUE 76 3 DISETOR 
   2-SEP 1996 TRUE WHEEL-10 1 DISETOR 
  30-JUN 1996 TRUE WHEEL-42 8 DISETOR 
  30-JUN-1996 SEPEDA SPEC 54 10 DISETOR 
  30-MAY-1996 SEPEDA SPEC 10 2 DISETOR 
  30-MAY-1996 SPEC SEPEDA 23 8 DISETOR 
  17-JAN-1996 SEPEDA SPEC 76 11 DISETOR 
  17-JAN-1996 LE Shoppe 76 5 DISETOR 
   1-JUN-1996 LE Shoppe 10 3 DISETOR 
   1-SEPEDA AAA-1996 10 Jun 1 DISETOR 
   1-JUL-1996 SEPEDA AAA 76 4 DISETOR 
   1-JUL-1996 SEPEDA AAA 46 14 DISETOR 
  11-JUL-1996 jack SEPEDA 76 14 DISETOR 

diproses terhadap kriteria subquery:

  SELECT URAIAN 
  BAGIAN DARI P 
  WHERE PARTNUM P. = O. PARTNUM 
ANALISIS:

Operasi ini mengembalikan URAIAN setiap baris BAGIAN mana P. PARTNUM = O. PARTNUM. Penjelasan di atas kemudian dibandingkan dalam klausa WHERE:

 WHERE 'JALAN SEPEDA' =

Karena setiap baris adalah diperiksa, subquery dalam subquery berkorelasi dapat memiliki lebih dari satu nilai. Bagaimanapun, jangan mencoba kembali beberapa kolom atau kolom yang tidak membuat akal dalam konteks klausa WHERE. Nilai kembali masih harus menyesuaikan terhadap operasi yang ditetapkan dalam klausul WHERE. Misalnya, dalam query baru saja Anda lakukan,HARGA kembali untuk membandingkan dengan JALAN SEPEDA akan memiliki hasil sebagai berikut:

INPUT / OUTPUT:
  SELECT * 
  Hai DARI Pesanan 
  WHERE 'JALAN SEPEDA' = 
  (SELECT HARGA 
  BAGIAN DARI P 
  WHERE PARTNUM P. = O. PARTNUM) 

  kesalahan konversi dari string "JALAN SEPEDA" 

Berikut contoh lain dari sesuatu yang tidak boleh dilakukan:

  SELECT * 
  DARI O Pesanan 
  WHERE 'JALAN SEPEDA' = 
  (SELECT * 
  BAGIAN DARI P 
  WHERE PARTNUM P. = O. PARTNUM) 
ANALISIS:

SELECT ini menyebabkan Jenderal Perlindungan Fault pada sistem operasi Windows saya. Mesin SQL tidak bisa berhubungan semua kolom di BAGIAN dengan operator =.

subqueries terkorelasi juga dapat digunakan dengan GROUP BY dan HAVING klausa. Permintaan berikut menggunakan subquery berkorelasi untuk menemukan urutan total rata-rata untuk bagian tertentu dan kemudian menerapkan nilai rata-rata untuk menyaring total order dikelompokkan berdasarkan PARTNUM:

INPUT / OUTPUT:
  SELECT O. PARTNUM, SUM (O. KUANTITAS * P. HARGA), COUNT (PARTNUM) 
  DARI O pesanan, P BAGIAN 
  WHERE PARTNUM P. = O. PARTNUM 
  GROUP BY O. PARTNUM 
  HAVING SUM (O. KUANTITAS * P. HARGA)> 
  (SELECT AVG (O1.QUANTITY * P1.PRICE) 
  BAGIAN DARI P1, pesanan O1 
  WHERE P1.PARTNUM = O1.PARTNUM 
  DAN P1.PARTNUM = O. PARTNUM) 

      PARTNUM COUNT SUM 
  =========== =========== =========== 

           10 8.400,00 4 
           23 4.906,30 2 
           76 19.610,00 5 
ANALISIS:

subquery tidak hanya menghitung satu

  AVG (O1.QUANTITY * P1.PRICE) 

Karena hubungan antara permintaan dan subquery itu,

  DAN P1.PARTNUM = O. PARTNUM 

rata-rata ini dihitung untuk setiap kelompok bagian dan kemudian dibandingkan:

  HAVING SUM (O. KUANTITAS * P. HARGA)> 

TIP: Bila menggunakan subqueries berkorelasi dengan GROUP BY dan HAVING, kolom dalam klausa HAVING harus ada di klausa SELECT baik atau klausa GROUP BY. Jika tidak, Anda mendapatkan pesan kesalahan di sepanjang baris kolom referensi tidak valid karena subquery yang ditimbulkan untuk masing-masing kelompok, tidak setiap baris. Anda tidak dapat membuat perbandingan yang valid untuk sesuatu yang tidak digunakan dalam pembentukan kelompok.


Menggunakan ada, APAPUN, dan SEMUA

Penggunaan kata kunci yang ada, APAPUN, dan SEMUA tidak intuitif jelas bagi pengamat biasa. Ada mengambil subquery sebagai argumen dan mengembalikan TRUE jika kembali subquery apa saja dan FALSE jika set hasil kosong. Sebagai contoh:

INPUT / OUTPUT:
  SELECT NAMA, ORDEREDON 
  Dari pesanan 
  WHERE ada 
  (SELECT * 
  Dari pesanan 
  WHERE NAMA TRUE WHEEL '=') 

  NAMA ORDEREDON 
  ========== =========== 

  TRUE WHEEL 15-MAY-1996 
  TRUE WHEEL 19-MAY-1996 
  TRUE WHEEL 2-SEP-1996 
  TRUE WHEEL 30-JUN-1996 
  SEPEDA SPEC 30-JUN-1996 
  SEPEDA SPEC 30-MAY-1996 
  SEPEDA SPEC 30-MAY-1996 
  SEPEDA SPEC 17-JAN-1996 
  LE Shoppe 17-JAN-1996 
  LE Shoppe 1-JUN-1996 
  AAA SEPEDA 1-JUN-1996 
  AAA SEPEDA 1-JUL-1996 
  AAA SEPEDA 1-JUL-1996 
  Jacks SEPEDA 11-JUL-1996 
ANALISIS:

Bukan yang Anda harapkan. The subquery dalam ada dievaluasi hanya sekali dalam contoh ini berkorelasi. Karena kembali dari subquery memiliki setidaknya satu baris, ada mengevaluasi TRUEdan semua baris dalam query dicetak. Jika Anda mengubah subquery seperti yang ditunjukkan berikutnya, Anda tidak akan mendapatkan kembali hasil apapun.

 SELECT NAMA, ORDEREDON dari pesanan ada WHERE (SELECT * FROM Orders WHERE NAME = 'kebanyakan tidak berbahaya')
ANALISIS:

Ada dievaluasi ke FALSE. subquery tidak menghasilkan hasil yang disetel karena sebagian besar tidak berbahaya tidak salah satu nama Anda.


CATATAN: Perhatikan penggunaan * SELECT di dalam subquery tidak ada. Ada tidak peduli berapa banyak kolom dikembalikan.


Anda bisa menggunakan cara ini ada untuk memeriksa keberadaan baris tertentu dan mengontrol output dari query Anda berdasarkan apakah mereka ada.

Jika Anda menggunakan ada dalam subquery berkorelasi, itu dievaluasi untuk setiap kasus yang tersirat dalam hubungan kita atur. Sebagai contoh:

INPUT / OUTPUT:
  SELECT NAMA, ORDEREDON 
  DARI O Pesanan 
  WHERE ada 
  (SELECT * 
  DARI PELANGGAN C 
  MANA NEGARA 'NE =' 
  C. NAMA DAN = O. NAMA) 

  NAMA ORDEREDON 
  ========== =========== 

  TRUE WHEEL 15-MAY-1996 
  TRUE WHEEL 19-MAY-1996 
  TRUE WHEEL 2-SEP-1996 
  TRUE WHEEL 30-JUN-1996 
  AAA SEPEDA 1-JUN-1996 
  AAA SEPEDA 1-JUL-1996 
  AAA SEPEDA 1-JUL-1996 

Ini sedikit modifikasi pertama Anda, kembali permintaan berkorelasi semua toko sepeda dari Nebraska yang membuat perintah. The subquery berikut ini dijalankan untuk setiap baris dalam query berkorelasi pada nama PELANGGAN dan nama perintah:

 (SELECT * FROM PELANGGAN WHERE C NEGARA 'NE =' DAN NAMA C. = O. NAMA)
ANALISIS:

Ada adalah TRUE bagi mereka baris yang memiliki nama yang sesuai pada PELANGGAN berlokasi di NE. Jika tidak, ia mengembalikan FALSE.

Terkait erat dengan ada adalah kata kunci APAPUN, SEMUA, dan BEBERAPA dan. APAPUN BEBERAPA adalah identik dalam fungsi. Seorang yang optimis akan mengatakan fitur ini memberikan pengguna dengan pilihan. Seorang pesimis akan melihat kondisi ini sebagai satu lagi komplikasi. Lihatlah query ini:

INPUT:
  SELECT NAMA, ORDEREDON 
  Dari pesanan 
  WHERE NAME = APAPUN 
  (SELECT NAMA 
  Dari pesanan 
  WHERE NAMA TRUE WHEEL '=')
OUTPUT:
  NAMA ORDEREDON 
  ========== =========== 

  TRUE WHEEL 15-MAY-1996 
  TRUE WHEEL 19-MAY-1996 
  TRUE WHEEL 2-SEP-1996 
  TRUE WHEEL 30-JUN-1996 
ANALISIS:

APAPUN membandingkan output dari subquery berikut untuk tiap baris dalam query, kembali TRUE untuk setiap baris dari query yang memiliki hasil dari subquery itu.

  (SELECT NAMA 
  Dari pesanan 
  WHERE NAMA TRUE WHEEL '=') 

Mengganti APAPUN dengan BEBERAPA menghasilkan hasil yang sama:

INPUT / OUTPUT:
 SELECT NAMA, ORDEREDON dari pesanan WHERE NAME = BEBERAPA SELECT NAMA (dari perintah WHERE NAMA TRUE WHEEL '=') NAMA ORDEREDON ========== =========== TRUE WHEEL 15 - MUNGKIN-1996 WHEEL TRUE 19-MUNGKIN-1996 WHEEL TRUE 2-September-1996 WHEEL TRUE 30-Juni-1996
ANALISIS:

Anda mungkin telah memperhatikan kesamaan untuk DI. Permintaan yang sama menggunakan DI adalah sebagai berikut:

INPUT / OUTPUT:
  SELECT NAMA, ORDEREDON 
  Dari pesanan 
  DI MANA NAMA 
  (SELECT NAMA 
  Dari pesanan 
  WHERE NAMA TRUE WHEEL '=') 

  NAMA ORDEREDON 
  ========== =========== 

  TRUE WHEEL 15-MAY-1996 
  TRUE WHEEL 19-MAY-1996 
  TRUE WHEEL 2-SEP-1996 
  TRUE WHEEL 30-JUN-1996 
ANALISIS:

Seperti yang Anda lihat, DALAM mengembalikan hasil yang sama seperti APAPUN dan BEBERAPA. Apakah dunia sudah gila? Belum. Dapat DALAM melakukan ini?

INPUT / OUTPUT:
  SELECT NAMA, ORDEREDON 
  Dari pesanan 
  WHERE NAMA> APAPUN 
  (SELECT NAMA 
  Dari pesanan 
  WHERE NAMA Jacks SEPEDA '=') 

  NAMA ORDEREDON 
  ========== =========== 

  TRUE WHEEL 15-MAY-1996 
  TRUE WHEEL 19-MAY-1996 
  TRUE WHEEL 2-SEP-1996 
  TRUE WHEEL 30-JUN-1996 
  LE Shoppe 17-JAN-1996 
  LE Shoppe 1-JUN-1996 

Jawabannya adalah tidak. DI bekerja seperti beberapa sama dan. APAPUN BEBERAPA dapat digunakan dengan operator relasional lain seperti lebih besar dari atau kurang dari. Tambahkan tool ini untuk kit Anda.

ALL TRUE kembali hanya jika semua hasil subquery sebuah memenuhi kondisi tersebut. Anehnya, SEMUA paling sering digunakan sebagai ganda negatif, seperti dalam query ini:

INPUT / OUTPUT:
  SELECT NAMA, ORDEREDON 
  Dari pesanan 
  WHERE NAMA <> SEMUA 
  (SELECT NAMA 
  Dari pesanan 
  WHERE NAMA Jacks SEPEDA '=') 

  NAMA ORDEREDON 
  ========== =========== 

  TRUE WHEEL 15-MAY-1996 
  TRUE WHEEL 19-MAY-1996 
  TRUE WHEEL 2-SEP-1996 
  TRUE WHEEL 30-JUN-1996 
  SEPEDA SPEC 30-JUN-1996 
  SEPEDA SPEC 30-MAY-1996 
  SEPEDA SPEC 30-MAY-1996 
  SEPEDA SPEC 17-JAN-1996 
  LE Shoppe 17-JAN-1996 
  LE Shoppe 1-JUN-1996 
  AAA SEPEDA 1-JUN-1996 
  AAA SEPEDA 1-JUL-1996 
  AAA SEPEDA 1-JUL-1996 
ANALISIS:

Ini semua orang kembali pernyataan kecuali jack SEPEDA>. <SEMUA mengevaluasi TRUE hanya jika set hasilnya tidak mengandung apa yang ada di kiri> <.

Ringkasan

Hari ini Anda melakukan latihan yang melibatkan puluhan subqueries. Anda belajar bagaimana menggunakan salah satu bagian yang paling penting dari SQL. Anda juga menangani salah satu bagian yang paling sulit dari SQL: sebuah subquery berkorelasi. The subquery berkorelasi menciptakan hubungan antara permintaan dan subquery yang dievaluasi untuk setiap instance dari hubungan itu. Jangan terintimidasi oleh panjang query. Anda dapat dengan mudah memeriksa mereka satu subquery pada satu waktu.

Iklan