Kueri secara sintaksis adalah SQL, bahkan jika table_b
tidak memiliki name
kolom. Alasannya adalah resolusi ruang lingkup.
Ketika kueri diuraikan, pertama-tama diperiksa apakah table_b
memiliki name
kolom. Karena tidak, maka table_a
diperiksa. Itu akan menimbulkan kesalahan hanya jika tabel tidak memiliki name
kolom.
Akhirnya kueri dijalankan sebagai:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
Adapun hasil kueri akan memberikan, untuk setiap baris table_a
, subquery (select name from table_b)
- atau (select a.name from table_b b)
- adalah tabel dengan satu kolom dengan nilai yang sama a.name
dan baris sebanyak table_b
. Jadi, jika table_b
memiliki 1 baris atau lebih, kueri berjalan sebagai:
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
atau:
select a.*
from table_a a
where a.name = a.name ;
atau:
select a.*
from table_a a
where a.name is not null ;
Jika table_b
kosong, kueri tidak akan mengembalikan baris (thnx ke @ughai untuk menunjukkan kemungkinan itu).
Itu (fakta bahwa Anda tidak mendapatkan kesalahan) mungkin adalah alasan terbaik bahwa semua referensi kolom harus diawali dengan nama tabel / alias. Jika kueri adalah:
select a.* from table_a where a.name in (select b.name from table_b);
Anda akan langsung mendapat kesalahan. Ketika awalan tabel dihilangkan, tidak sulit untuk kesalahan tersebut terjadi, terutama dalam permintaan yang lebih kompleks, dan bahkan yang lebih penting, tidak diperhatikan.
Baca juga di Oracle docs: Resolusi Nama dalam Pernyataan SQL Statis , contoh serupa B-6 dalam tangkapan dalam dan rekomendasi dalam paragraf Menghindari Penangkapan Dalam di paragraf SELECT dan DML Statement :
Kualifikasi setiap referensi kolom dalam pernyataan dengan alias tabel yang sesuai.
Karena
Itu berarti untuk menentukan apakah subquery berkorelasi Oracle harus mencoba untuk menyelesaikan nama dalam subquery termasuk konteks pernyataan luar juga. Dan untuk yang tidak diperbaiki
name
itu satu-satunya resolusi yang mungkin.sumber
Tidak ada
name
bidang dalamtable_b
sehingga Oracle mengambil satu daritable_a
. Saya mencobaEXPLAIN PLAN
tetapi ini memberi saya hanya adaTABLE ACCESS
FULL
. Saya berasumsi bahwa ini akan menghasilkan semacam Produk Cartesian antara kedua tabel yang menghasilkan daftar semua namatable_a
yang dikembalikan oleh sub-kueri.sumber
from table_a where ...
. Ini akan mengembalikan semua baristable_a
kecuali yangname
nol.TABLE ACCESS FULL
hanyalah cara Oracle untuk memberi tahu Anda bahwa ia melakukan pemindaian berurutan.