簡體   English   中英

INNER JOIN的不明確的列名SQL錯誤:為什么?

[英]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.foot2.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.foot2.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM