[英]Ambiguous column name SQL error with INNER JOIN: Why?
以下代碼將用於從兩個表中選擇數據:
SELECT t1.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 ON t1.foo=t2.foo
我可以這么容易寫
SELECT t2.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 ON t1.foo=t2.foo
t1.foo
或t2.foo
:一個或六個中的六個。 為什么不只是foo
?
我一直在想,為什么SQL服務器只是在沒有指定一個表或另一個表的情況下自動返回數據,因為選擇完全是任意的(據我所知)。
我可以編寫一個你需要指定表格的場景,例如
SELECT t1.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE t2 ON t1.foo+=t2.foo
但是,根據我的經驗,這種情況遠非常態。
任何人都可以告訴我為什么語言的設計,以便我必須在我的代碼中做出這個看似隨意的決定?
因為MS SQL中的相等並不一定意味着它們在您想要的值中相等。 考慮foo的以下2個值:“Bar”,“baR”。 Sql會認為它們在連接方面是相同的,因為比較中固有的不區分大小寫,但是你要求哪一個? SQL Server不知道,也無法猜測。 你必須明確告訴它。
編輯:正如@Lukas Eder提出的那樣,並非所有SQL實現都使用不區分大小寫的比較。 我知道MS SQL使用不區分大小寫,我的答案正是考慮到這個概念。
你的推理並不完全正確。 雖然t1.foo = t2.foo
可能成立,但這並不意味着它們是相同的。 一些例子:
VARCHAR(1)
另一個VARCHAR(2)
VARCHAR(1)
另一個NUMBER(1)
t1
可以是一個簡單的表,而t2
是一個視圖(或嵌套的選擇),它對foo
的值進行超復雜的計算。 在某些RDBMS中, foo
的投影成本可能不同。 還有其他幾十個原因,為什么寫foo
會很尷尬
如果您確定列表示相同的內容,則可以使用USING子句加入。
SELECT foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 USING (foo);
否則,無法保證t1.foo與t2.foo相同
在這種情況下,您有一個INNER JOIN,因此很明顯該決定是任意的。 但是在很多情況下,即使你加入FOO,2也不一樣。
EX:在LEFT JOIN的情況下,如果你有類似ON t1.foo = t2.foo + / - / whater的話
引擎需要您的輸入才能知道從哪里獲取數據。
你需要做出這個決定的原因是它不是任意的。 系統不知道哪個表包含您想要的數據。 你需要指定它。 當系統設計執行計划時,它不會確定哪些列在兩個表中包含相同的數據。 就它而言,這兩列可能有不同的數據。 它不打算推斷,因為你說這些列是相同的,當沒有指定一列時它可以顯示任一列。
在那種特殊情況下, t1.foo
和t2.foo
是相同的東西,但引擎沒有針對它進行優化(如果是的話會引起混淆)。 如果你的加入做了一些他們可能不一樣的事情,比如這樣呢?
SELECT t2.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 ON t1.foo<t2.foo
由於我們使用<
,foo對t1和t2可能是非常不同的東西。 在這種情況下,引擎無法“猜測”。
僅僅因為這些體驗在您的體驗中“遠非常規”,引擎必須允許它,否則會使某些類型的查詢極難編寫。
SQL沒有這樣做,因為它根本無法解決歧義。 (但是你注意到它們是等價的。)
對於應用程序生命周期,最好自己解決它們,因為如果列更改名稱或連接類型發生更改,則代碼不太可能被破壞,並且您的意圖更明顯。 但是我確信這些好處不是故意的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.