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

时间:2018-05-23 06:38:58

标签: sql sql-server

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

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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。它的教程和帮助文件已满,。但即便是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:内部联接

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?