2个sql查询有什么区别?

时间:2016-11-21 15:51:24

标签: sql oracle

我有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';

错误是

  

第1行的错误:ORA-00904:“COUPON_ADDRESS”。“MERCHANT_ADDRESS”:标识符无效

3 个答案:

答案 0 :(得分: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';

它没有工作的原因是解析器评估查询的顺序。可能未知栏目的表尚未进行评估。

答案 1 :(得分:1)

JOIN的优先级高于,子句中的FROMONJOIN的一部分,所以它只会看到哪些开始加入,包括之前的联接。

所以:

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语法。

答案 2 :(得分:0)

Sagi的回答是正确的。您的版本不起作用的原因是因为FROM子句中逗号的范围规则。哦,我提到过:从不FROM子句中使用逗号。 始终使用明确的JOIN语法。

您的FROM子句评估为:

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

我认为这很明显为什么你会收到错误。