Sql 为什么内部联接有一个关键字?
我谨此陈辞: 笛卡尔连接由select语句指定,不带特殊符号。这是合理的,因为您从SELECT语句中提取了所有可能的有序n元组组合。SELECT就是这么做的Sql 为什么内部联接有一个关键字?,sql,Sql,我谨此陈辞: 笛卡尔连接由select语句指定,不带特殊符号。这是合理的,因为您从SELECT语句中提取了所有可能的有序n元组组合。SELECT就是这么做的 SELECT table1.column1, table2.column2... FROM table1, table2; 如果要施加条件,可以使用WHERE来请求它们。因此,我希望内部联接不会有特殊关键字,因为您可以只使用笛卡尔联接,然后限制为,其中table1.column1=table2.column2 相反,符号是这样存在的:
SELECT table1.column1, table2.column2...
FROM table1, table2;
如果要施加条件,可以使用WHERE
来请求它们。因此,我希望内部联接不会有特殊关键字,因为您可以只使用笛卡尔联接,然后限制为,其中table1.column1=table2.column2
相反,符号是这样存在的:
SELECT table1.column1, table2.column2...
FROM table1
INNER JOIN table2
ON table1.common_field = table2.common_field;
我的问题是:为什么?在FROM
子句中列出表,并将所有筛选器(包括连接条件)放在WHERE
子句中是一种老方法。曾经有一段时间,这种方法(带有一些扩展语法)甚至被用于外部联接(至少在Oracle上)
但是现在的标准方法是使用显式连接。那为什么呢
当您有多个联接,并且可能筛选不属于任何联接的条件时,使用显式联接语法更具可读性
考虑:
SELECT emp.ID, mgr.ID, dept.NAME, asset.TAG_NO
FROM employee emp, employee mgr, department dept, asset
WHERE emp.HIRE_DT > :grandfather_date
AND emp.MGR_ID = mgr.ID
AND dept.NAME != 'IT'
AND asset.EMP_ID = mgr.ID
AND asset.TYPE_CD == 'D'
现在,在解决此查询的问题时,您可能需要快速评估以下内容:我是否正确地联接了所有表?如果一行显示员工a和经理B,则该行上的资产分配给谁?谁必须参与才能被排除在报告之外
仔细组织查询中的代码可以帮助您更快、更可靠地回答这些问题。(当我们开始讨论时,这是一个规模相当小的查询;查询越大,问题就越重要。)
目前的标准联接语法强加了一些您应该想要的合理结构:
SELECT emp.ID, mgr.ID, dept.NAME, asset.TAG_NO
FROM employee emp
INNER JOIN employee mgr
ON emp.MGR_ID = mgr.ID
INNER JOIN department dept
-- OOPS! This was missing above!
ON emp.DEPT_ID = dept.ID
INNER JOIN asset
ON asset.EMP_ID = mgr.ID
WHERE emp.HIRE_DT > :grandfather_date
AND dept.NAME != 'IT'
AND asset.TYPE_CD == 'D'
谓词是或不是连接条件的事实现在是显式的。您知道哪个连接受给定谓词的约束,因此您知道是否对所有连接都有约束(事实上,除非您特别使用交叉连接语法,否则您必须…因为这几乎总是正确的)。如果您需要知道“我们谈论的是谁的资产(员工或经理)”,您知道直接转到asset
表的连接条件来检查它
如果有很多非连接条件,您可能仍然需要考虑组织where子句;你仍然需要格式化你的代码。但是如果你做了这些事情,待命支持人员诅咒你的名字的理由就会少很多。在FROM
子句中列出表,并将所有过滤器(包括连接条件)放在中,而子句是老办法。曾经有一段时间,这种方法(带有一些扩展语法)甚至被用于外部联接(至少在Oracle上)
但是现在的标准方法是使用显式连接。那为什么呢
当您有多个联接,并且可能筛选不属于任何联接的条件时,使用显式联接语法更具可读性
考虑:
SELECT emp.ID, mgr.ID, dept.NAME, asset.TAG_NO
FROM employee emp, employee mgr, department dept, asset
WHERE emp.HIRE_DT > :grandfather_date
AND emp.MGR_ID = mgr.ID
AND dept.NAME != 'IT'
AND asset.EMP_ID = mgr.ID
AND asset.TYPE_CD == 'D'
现在,在解决此查询的问题时,您可能需要快速评估以下内容:我是否正确地联接了所有表?如果一行显示员工a和经理B,则该行上的资产分配给谁?谁必须参与才能被排除在报告之外
仔细组织查询中的代码可以帮助您更快、更可靠地回答这些问题。(当我们开始讨论时,这是一个规模相当小的查询;查询越大,问题就越重要。)
目前的标准联接语法强加了一些您应该想要的合理结构:
SELECT emp.ID, mgr.ID, dept.NAME, asset.TAG_NO
FROM employee emp
INNER JOIN employee mgr
ON emp.MGR_ID = mgr.ID
INNER JOIN department dept
-- OOPS! This was missing above!
ON emp.DEPT_ID = dept.ID
INNER JOIN asset
ON asset.EMP_ID = mgr.ID
WHERE emp.HIRE_DT > :grandfather_date
AND dept.NAME != 'IT'
AND asset.TYPE_CD == 'D'
谓词是或不是连接条件的事实现在是显式的。您知道哪个连接受给定谓词的约束,因此您知道是否对所有连接都有约束(事实上,除非您特别使用交叉连接语法,否则您必须…因为这几乎总是正确的)。如果您需要知道“我们谈论的是谁的资产(员工或经理)”,您知道直接转到asset
表的连接条件来检查它
如果有很多非连接条件,您可能仍然需要考虑组织where子句;你仍然需要格式化你的代码。但是如果你做了这些事情,待命支持人员就没有什么理由诅咒你的名字了。我认为你只需要了解隐式连接和显式连接的区别
下面提到的链接将帮助您
我认为您只需要了解隐式连接和显式连接的含义以及它们之间的区别
下面提到的链接将帮助您
因为ANSI-92标准不推荐隐式的JOIN
语法(WHERE
子句中的逗号)。它有助于更清晰的JOIN
表示法-尤其是OUTER JOIN
s。我想你会在下面的链接中找到一个wser,除了它是一个更清晰、更清晰的语法外,它还有助于防止首先执行笛卡尔JOIN
。强制所有内容都是笛卡尔式的连接
(或交叉连接
),然后在中过滤结果,其中
子句将在某个点上导致意外的交叉连接
。重复前面的一点,这是25年前不推荐的!一些DBMS产品甚至不再支持以这种语法进行的外部联接
s(例如SQL Server 2012
及更高版本)。只需使用explicitJOIN
s即可。对于笛卡尔乘积,逗号是不合理的<代码>交叉连接
现在是标准,应该使用。因为ANSI-92标准不推荐隐式连接
语法(WHERE
子句中的逗号)。它使JOIN
符号更加清晰,尤其是OUTER-JOIN
s。我想你会明白的