两个查询有何不同?两者都给出了相同的结果

问题描述 投票:1回答:3
select a.MenuID,a.MenuStructureID,b.MenuName from 
MenuStructure a, Menu b
where b.MenuID=a.MenuID

select a.MenuID,a.MenuStructureID,b.MenuName from 
MenuStructure a
join Menu b  
on b.MenuID=a.MenuID

如果两者都相同,我应该选择哪一个?为什么?

sql sql-server
3个回答
2
投票

对于非常简单的查询,很难证明使用JOIN而不是,。如你所见,两者非常相似。如果布局略有不同,哪个更为明显......

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a
,
  Menu b  
    WHERE b.MenuID = a.MenuID

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a
INNER JOIN
  Menu b  
    ON b.MenuID = a.MenuID

看起来好像用,代替JOIN而用WHERE代替ON ......

但是,一旦你编写了更复杂的查询,用JOIN表示法就会更容易阅读,并且首先变得更难犯错误......

缺少谓词

例如,这两个都以相同的方式是错误的,但只有JOIN表示法会给出语法错误(并且首先更容易在视觉上发现)。

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a
,
  Menu b  
,
  Items i  
    WHERE b.MenuID = a.MenuID

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a
INNER JOIN
  Menu b  
    ON b.MenuID = a.MenuID
INNER JOIN
  Items i

第一个查询运行正常,它相当于CROSS JOIN Items i,运行成本高,调试难度大。

但是,由于缺少谓词JOIN Items i(或类似的),第二个查询在ON i.MenuID = b.MenuID附近有语法错误。

这种语法错误对于及早发现拼写错误和其他愚蠢错误非常有帮助。

外联合

与使用OUTER JOIN相比,使用(+)时更加清晰

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a
LEFT OUTER JOIN
  Menu b  
    ON b.MenuID = a.MenuID

这与旧的符号相比......

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a, Menu b
WHERE
  b.MenuID=a.MenuID(+)

OUTER JOIN不仅更容易阅读,如果你误输入以下内容,你会得到不同的结果! (微妙的错别字再次合法,但难以发现后果。)

SELECT
  a.MenuID, a.MenuStructureID, b.MenuName
FROM
  MenuStructure a, Menu b
WHERE
  a.MenuID=b.MenuID(+)

甚至有些表达式可以用OUTER JOIN编写,不能用,(+)编写。 (我会留给你研究。)

因此,几乎所有主要发行版都建议不要使用(+) ......

  • 如果你不打算使用(+)你需要使用OUTER JOIN
  • 如果你打算使用OUTER JOIN,你就不会使用,
  • 真的真的不要把,OUTER JOIN混在一起......

使用,进行传播的主要“罪魁祸首”之一是Oracle。它的教程和帮助文件充满了,。但即使是甲骨文也建议不要使用(+)

结论

在所有JOIN语法中更容易阅读,并且更有可能在,可能给出静默失败的情况下给出语法错误。

当引入变得复杂的OUTER JOIN时,甚至导致,(+)无法处理的情况。

更不用说JOIN是在1992年编纂的。为什么你会使用比那更老的标准!?


2
投票

通常,显式连接(底部版本)更易于读取/调试。因此,如果其他人需要使用相同的代码,或者您需要在很长一段时间后对其进行审核。


1
投票

如果你想加入两个表,你可以用两种方式完成。一个使用符合ANSI标准的INNER JOIN,另一个使用旧式连接

但建议不要使用旧式连接。这就是原因。

让我们创建以下数据集

CREATE TABLE item_master(item_id INT, item_description VARCHAR(100));
CREATE TABLE item_sales(item_id INT, sales_date DATETIME, qty INT);
INSERT INTO item_master
SELECT 1,'Samsung' UNION ALL
SELECT 2,'LG'; 
INSERT INTO item_sales
SELECT 1,'2015-04-03 12:10:10',2 UNION ALL
SELECT 2,'2015-06-11 07:22:00',3 UNION ALL
SELECT 2,'2015-06-12 11:00:48',22; 

如果要显示每个item_item描述以及已售出的总数量,您可以使用此代码

方法1:INNER JOIN

SELECT item.item_description,SUM(details.qty) AS qty FROM item_master AS item
INNER JOIN item_sales AS details
ON item.item_id=details.item_id
GROUP BY item.item_description;

方法2:使用WHERE子句的旧样式连接

SELECT item.item_description,SUM(details.qty) AS qty FROM item_master AS item
,item_sales AS details
WHERE item.item_id=details.item_id
GROUP BY item.item_description;

两者都返回以下结果

item_description qty
 ------------------- ----------
 LG 25
 Samsung 2

但是如果你错误地省略了方法2中的WHERE条件会发生什么

SELECT item.item_description,SUM(details.qty) AS qty FROM item_master AS item
,item_sales AS details
GROUP BY item.item_description;

结果是

item_description qty
 ------------------- ----------
 LG 27
 Samsung 27

这是完全错误的,因为它导致交叉连接

但是如果没有指定JOIN,方法1将抛出错误

SELECT item.item_description,SUM(details.qty) AS qty FROM item_master AS item
INNER JOIN item_sales AS details
GROUP BY item.item_description;

错误是

Incorrect syntax near the keyword 'group'.

参考:SQL SERVER – Why Should You Not to Use Old Style JOIN?

© www.soinside.com 2019 - 2024. All rights reserved.