แบบสอบถามถูกต้องตามหลักไวยากรณ์ SQL แม้ว่าtable_bจะไม่มีnameคอลัมน์ เหตุผลก็คือการแก้ไขขอบเขต
เมื่อแบบสอบถามแยกวิเคราะห์มันจะถูกตรวจสอบก่อนว่าtable_bมีnameคอลัมน์ เนื่องจากไม่เป็นเช่นนั้นtable_aจะถูกตรวจสอบ มันจะโยนข้อผิดพลาดก็ต่อเมื่อไม่มีตารางใดมีnameคอลัมน์
ในที่สุดแบบสอบถามจะถูกดำเนินการเป็น:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
สำหรับผลลัพธ์ที่แบบสอบถามจะให้สำหรับทุกแถวของtable_aแบบสอบถามย่อย(select name from table_b)- หรือ(select a.name from table_b b)- คือตารางที่มีคอลัมน์เดียวที่มีa.nameค่าเดียวกันและมีจำนวนแถวเท่าtable_bกัน ดังนั้นหากtable_bมี 1 แถวขึ้นไปเคียวรีจะทำงานเป็น:
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
หรือ:
select a.*
from table_a a
where a.name = a.name ;
หรือ:
select a.*
from table_a a
where a.name is not null ;
ถ้าtable_bว่างเปล่าแบบสอบถามจะไม่ส่งคืนแถวใด (ขอบคุณถึง @ughai สำหรับการชี้ความเป็นไปได้นั้น)
นั่น (ความจริงที่ว่าคุณไม่ได้รับข้อผิดพลาด) อาจเป็นเหตุผลที่ดีที่สุดที่การอ้างอิงคอลัมน์ทั้งหมดควรจะนำหน้าด้วยชื่อตาราง / นามแฝง หากแบบสอบถามคือ:
select a.* from table_a where a.name in (select b.name from table_b);
คุณจะได้รับข้อผิดพลาดทันที เมื่อละเว้นคำนำหน้าตารางจะไม่ยากสำหรับความผิดพลาดดังกล่าวที่จะเกิดขึ้นโดยเฉพาะอย่างยิ่งในการค้นหาที่ซับซ้อนมากขึ้นและที่สำคัญกว่านั้นก็ไม่ต้องไปสังเกต
อ่านเพิ่มเติมในOracle docs: การแก้ปัญหาชื่อในงบ SQL แบบคงที่ตัวอย่างที่คล้ายกัน B-6 ในการดักจับด้านในและคำแนะนำในการหลีกเลี่ยง Inner Capture ในย่อหน้าSELECT และ DML Statement :
รับรองการอ้างอิงแต่ละคอลัมน์ในคำสั่งด้วยนามแฝงตารางที่เหมาะสม