2016-11-21 93 views
0

我有2個SQL查詢其中一個工作,但另一個給出錯誤。下面的查詢效果很好2個SQL查詢有什麼區別?

select /*ordered*/ coupon_address.coupon,merchant_address.id 
from merchant_address, 
    coupon_address, 
    customers c 
WHERE merchant_address.id = coupon_address.merchant_address 
    and c.CUSTOMER_ID = 'temp1' 
    AND sdo_within_distance(c.cust_geo_location,merchant_address.store_geo_location,'distance = 1 unit=MILE') = 'TRUE'; 

但下面的查詢不起作用,並且給出了一個錯誤

select /*ordered*/ coupon_address.coupon,merchant_address.id 
from coupon_address, 
     customers c 
    JOIN merchant_address ON merchant_address.id=coupon_address.merchant_address 
WHERE c.CUSTOMER_ID = 'temp1' 
    AND sdo_within_distance (c.cust_geo_location,merchant_address.store_geo_location, 'distance = 1 unit=MILE') = 'TRUE'; 

錯誤是

ERROR位於第1行:ORA-00904: 「COUPON_ADDRESS」。 「MERCHANT_ADDRESS」:無效標識符

+1

您正在將舊的,古老的,過時的和脆弱的隱式聯接與顯式的'JOIN'運算符混合。不要這樣做。 –

+2

如果使用ANSI語法,則必須將其用於所有表;如果您決定使用舊的Oracle連接語法(並且強烈建議不要這麼做),請對所有表執行 – Aleksej

+0

@a_horse_with_no_name將過時的連接與JOIN混合,意味着什麼? – raju

回答

6

不要混合顯式和隱式一起加入語法!他們總是會導致混亂和錯誤:

select /*ordered*/ coupon_address.coupon,merchant_address.id 
FROM coupon_address 
JOIN merchant_address 
    ON merchant_address.id=coupon_address.merchant_address 
JOIN customers c ON c.CUSTOMER_ID = 'temp1' 
WHERE sdo_within_distance (c.cust_geo_location, 
          merchant_address.store_geo_location, 
          'distance = 1 unit=MILE') = 'TRUE'; 

它不工作的原因是解析器評估查詢的順序。未知列的表可能尚未評估。

+0

會打賭這並不解決實際問題,而應該去評論。已經提出的評論。 – Alfabravo

+0

這確實奏效,雖然我不確定最近寫入的連接語句有什麼問題。 – raju

+0

問題是優化程序評估查詢的順序。未知列的表可能尚未評估。 @raju – sagi

1

JOIN具有比FROM子句中的,一個更高的優先級。 ONJOIN的一部分,因此它只能看到哪些開始加入,包括之前的加入。

所以:

select /*ordered*/ coupon_address.coupon,merchant_address.id 
from coupon_address, 
     customers c 
    JOIN merchant_address 
    ON merchant_address.id=coupon_address.merchant_address 

在本質上是:

select /*ordered*/ coupon_address.coupon,merchant_address.id 
from coupon_address, 
     (customers c 
    JOIN merchant_address 
    ON merchant_address.id=coupon_address.merchant_address) 

coupon_address尚未範圍。

正如其他人所說的,最好堅持一種連接方式,即SQL-92 join關鍵字或from子句中的較早逗號,並加入where子句中的條件。我更喜歡明確的join語法。

+0

錯! *不是最好堅持一種'join'。最好使用適當的顯式'JOIN'語法。 –

0

Sagi的回答是正確的。您的版本不起作用的原因是由於FROM條款中逗號周圍的範圍規則。哦,我提到:從來沒有FROM條款中使用逗號。 總是使用明確的JOIN語法。

from coupon_address, 
    (customers c JOIN 
     merchant_address 
     ON merchant_address.id = coupon_address.merchant_address 
    ) 

我想,這使得它顯而易見的,爲什麼你所得到的錯誤:爲

FROM條款進行評估。