Oracle
為什麼這個查詢有效?
我有兩個表,table_a (id, name) 和 table_b (id),假設在 Oracle 12c 上。
為什麼這個查詢不返回異常?
select * from table_a where name in (select name from table_b);
據我了解,甲骨文認為這是
select * from table_a where name = name;
但我不明白為什麼?
即使
table_b
沒有name
列,查詢也是語法正確的 SQL。原因是范圍解析。解析查詢時,首先檢查是否
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 文件:靜態 SQL 語句中的名稱解析,內部擷取中的類似範例 B-6以及避免 SELECT 和 DML 語句中的內部擷取段落中的建議:
使用適當的表別名限定語句中的每個列引用。