2016-08-15 24 views
2

我不知道爲什麼PostgreSQL的這句話產生不明確的引用錯誤:爲什麼列引用在INNER JOIN中不明確,但不在NATURAL JOIN中?

SELECT c from A JOIN B ON A.c = B.c; -- ERROR: column reference is ambiguous 

但不是這樣的:

SELECT c FROM A NATURAL JOIN B; -- OK 

在這兩種情況下A.c必須與B.c

+3

JOIN返回兩個表的C列。自然連接返回一個C列(相同的結果),「表免費」。 – jarlh

+0

@帕特里克,好吧,我寫了一條評論,而不是答案......無論如何,答案就在那裏。常規的'JOIN ... ON'返回兩列C(A.C和B.C),你需要指定你想要的。一個'NATURAL JOIN',還有一個'JOIN ... USING(C)',只返回一個C列。然後它不會是模棱兩可的! – jarlh

+0

那麼你有答案嗎? –

回答

1

如果你想在一個明確的一個明確的列引用加入使用using

select c 
from 
    a 
    inner join 
    b using (c) 

形式的使用條款(A,B,...)是簡寫ON left_table.a = right_table.a AND left_table.b = right_table.b ....此外,USING意味着每對等效列中只有一個將包含在連接輸出中,而不是兩者。

+1

這不回答問題。 – Patrick

0

NATURAL JOIN字段由列的名稱接合,因此,如果由行定義然後A.c = B.c匹配。使用USING短語時也是如此:匹配僅在普通的vanilla列名上進行。兩者之間的區別在於,第一個選項將所有匹配的列名連接在一起,而第二個選項則必須指定相似的列名,因此您可以選擇將哪些列名包含在連接中。

在加入ON短語的情況下,即使列名相同,這些行值的相等也不一定如此。考慮這種情況:

SELECT c 
FROM A 
JOIN B ON A.c = 6 * B.c; 

換句話說,即使兩個關係具有相同名稱的列,這些列從兩個關係行中的值不必是相同的,以進行匹配,因爲任何表達式的種類可能涉及任何一行或兩行的值。因此,爲什麼你需要明確你想從哪個關係中選擇行值。

+0

「只匹配普通的香草列名稱」 - 當然這些類型也必須是相同的(或「兼容的」)? – onedaywhen

+0

「明確你想從哪個關係中選擇行值」 - 我不認爲你的意思是「關係」。我認爲這應該是,「明確哪些範圍變量('A'或'B')屬性'c'涉及。」 – onedaywhen

0

還有一個在第二個查詢中加入結果的列名爲「c」。
還有兩個在您的第一個查詢中加入結果中名爲「c」的列。

因此,列名「c」在您的第一個示例中不明確,但不在您的第二個示例中。錯誤消息很明顯。這是它的程度。這兩個名爲「c」的列的值是否可能相同並不重要。該引用不明確,因此是錯誤消息。

SQL允許多列在結果集中具有相同的名稱。但是引用必須是明確的。一個表資格將使其明確:

SELECT a.c FROM a JOIN b ON a.c = b.c; 

或者:

SELECT b.c FROM a JOIN b ON a.c = b.c; 

爲什麼在第二個查詢命名爲 「C」 只有一個列?Quoting the manual:

NATURALUSING列表中提到,有相同名稱的兩個表中的所有列的簡寫。

和:

形式USING (a, b, ...)的條款可以簡寫ON left_table.a = right_table.a AND left_table.b = right_table.b .... 另外,USING意味着只有每對等效列 中的一個將被包括在所述加入輸出,不都。

大膽重視我的。