2个sql查询有啥区别?
Posted
技术标签:
【中文标题】2个sql查询有啥区别?【英文标题】:What is difference between 2 sql queries?2个sql查询有什么区别? 【发布时间】:2016-11-21 15:51:24 【问题描述】:我有 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”:标识符无效
【问题讨论】:
您将旧的、古老的、过时的和脆弱的隐式连接与显式的JOIN
运算符混合在一起。不要那样做。
如果你使用ANSI语法,你必须对所有的表都使用它;同样,如果您决定使用旧的 Oracle 连接语法(强烈建议不要这样做),请对所有表执行此操作
@a_horse_with_no_name 将过时的连接与 JOIN 混合是什么意思?
包含表定义
【参考方案1】:
永远不要将显式和隐式连接语法混合在一起!它们总是会导致混乱和错误:
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';
它不起作用的原因是解析器评估查询的顺序。可能未知列的表尚未评估。
【讨论】:
我敢打赌这并不能解决实际问题,而是应该作为评论。已经发表的评论。 这确实有效,但我不确定我写的加入语句有什么问题。 问题在于优化器评估查询的顺序。可能未知列的表尚未评估。 @raju @alfabravo 关于什么? :) 这是因为在您的原始查询中,您尝试使用 ANSI 语法将客户表内部连接到商家地址表,但连接条件是针对不同的表。如果你有from customers, coupon_address inner join merchant_address on merchant_address.id = coupon_address.merchant_address
,它可能会起作用,尽管我不推荐它。在整个查询过程中坚持使用一种连接语法,您不会感到困惑。【参考方案2】:
JOIN
的优先级高于 FROM
子句中的 ,
。 ON
是 JOIN
的一部分,因此它只能看到开始加入的内容,包括早期的加入。
所以:
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
语法。
【讨论】:
错了! 不最好坚持使用一种类型的join
。最好使用正确、明确的JOIN
语法。【参考方案3】:
Sagi 的回答是正确的。您的版本不起作用的原因是因为 FROM
子句中逗号周围的范围规则。哦,我有没有提到:从不在 FROM
子句中使用逗号。 总是使用明确的JOIN
语法。
您的 FROM
子句被评估为:
from coupon_address,
(customers c JOIN
merchant_address
ON merchant_address.id = coupon_address.merchant_address
)
我认为这很清楚你为什么会收到错误。
【讨论】:
以上是关于2个sql查询有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
在Oracle数据库条件查询语句中使用'%%','_%%'这两个有啥区别
SQL数据库中查询语句Order By和Group By有啥区别