แบบสอบถามถูกต้องตามหลักไวยากรณ์ 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 :
รับรองการอ้างอิงแต่ละคอลัมน์ในคำสั่งด้วยนามแฝงตารางที่เหมาะสม