考慮以下情況:
create table contract(contract_id bigint, client_id bigint, second_client_id bigint);
insert into contract
values(10, 1, 3),
(11, 2, 4),
(12, 3, 6)
;
create table client(client_id bigint, user_name varchar);
insert into client
values(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D'),
(5, 'E'),
(6, 'F')
;
我看不到以下查詢樣式的用例,但 Postgres(我已經測驗過)和可能的其他 SQL RDMS 服務允許查詢而不會引發錯誤/警告:
select *
from contract c
left join client ct1 on ct1.client_id = c.client_id
left join client ct2 on ct1.client_id = c.second_client_id
請注意,第二個連接不參考正在連接的表中的列(即,第二個client連接的別名為,ct2但連接子句中沒有ct2列)。我不明白為什么有人會想要這個結果,但是沒有警告或錯誤拋出。在大型表中,嘗試此連接并回傳 null 可能會浪費大量時間,只有這樣撰寫查詢的人才會意識到他們的錯誤。
好奇這種型別的查詢的任何用例,如果沒有,為什么沒有建立錯誤處理。
編輯:正如評論中所指出的,連接在語法上是正確的,因此不會引發錯誤 - 查詢計劃器在執行之前不會檢查連接功能。
uj5u.com熱心網友回復:
由于連接條件是一個布爾運算式,它只參考FROM子句中先前表中的列,所以它沒有任何問題。SQL 中沒有任何內容禁止您以這種方式撰寫交叉連接,實際上撰寫類似的東西并不罕見
FROM tab
LEFT JOIN LATERAL unnest(tab.arr)
ON TRUE
如此禁止似乎是不可能的,除了它會違反 SQL 標準。
你的愿望并不少見,它在代碼“do what I mean”(DWIM)下被稱為。我討厭那些認為他們比我更清楚我想要什么的系統,并以他們有用的警告來打擾我。
uj5u.com熱心網友回復:
您必須了解的重要一點是,連接不僅是比較來自兩個表的值的謂詞,而且是用于任意數量的表的謂詞。
就是這種情況,在 RDBMS 文獻中稱為“三角連接”,它涉及 3 個或更多表......
在您的查詢中,三角連接是真實的,也可以寫成:
select *
from contract c
left join client ct1 on ct1.client_id = c.client_id
left join client ct1 on ct1.client_id = c.second_client_id
CROSS JOIN ct2
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/426893.html
標籤:sql PostgreSQL
