SQL中ON子句和USING子句的区别

20
我正在做一个关于 Oracle 中连接的作业。在某个地方我遇到了瓶颈,即 USING 和 ON 子句之间的区别是什么。
我知道使用 ON 子句我们可以连接无限数量的表格。 但是使用 USING 子句能否连接无限数量的表格?如何做到? 你能用一个例子来解释一下吗?

2
文档非常好。 - Maxim Krizhanovsky
2
我不同意@MaximKrizhanovsky的观点,我认为文档非常不清晰。它没有说明它们是否等效或存在哪些差异。 - Rick Henderson
7个回答

42
  • USING子句:它允许您按名称指定连接键。

  • ON子句:这种语法允许您在两个表格中指定连接键的列名。

使用USING子句

如果多个列具有相同的名称,但您不想使用所有这些公共列进行连接,则使用USING子句。在语句中,列在USING子句中列出时不能有任何限定符,包括WHERE子句:

使用ON子句

当表格中的列名不匹配时,使用ON子句来连接表格。连接条件从WHERE子句的筛选条件中移除:

Oracle

select department_name, city
from departments
JOIN locations
USING (location_id); -- specify the same column name 
                     -- for both of the tables for the join
select department_name, city
from departments dept
join locations loc
on (dept.location_id = loc.id); -- specify different column name 
                                -- for the tables for the join.

16

除了上面的回答外,一个重要的区别是 ON 子句会分别保留每个连接表中的列,而 USING 子句会将连接表中的列合并成一列。如果您想仅在一个连接表中没有匹配行时保留结果集中的行,则这可能很重要。为此,通常会使用 OUTER JOIN 和 WHERE 子句中的条件,例如:

SELECT t1.*
  FROM TABLE_1 t1
  LEFT OUTER JOIN TABLE_2 t2
    ON (t2.KEY_FIELD = t1.KEY_FIELD)
  WHERE t2.KEY_FIELD IS NULL
在这种情况下,假设TABLE_2.KEY_FIELD是TABLE_2主键的一部分,因此如果TABLE_2中确实存在数据,则它永远不会为NULL。 如果在上述连接之后,在连接集中发现TABLE_2.KEY_FIELD包含NULL,则意味着找不到与相应的TABLE_1行匹配的TABLE_2行。 这有时可能很有用。
分享并享受。

7
除了以上的回答之外,using子句将只打印连接的列一次。
A.id  B.id
1      1
2      2
3      3

Select * from A JOIN B using(id);

输出结果将会是

id
1
2
3

但是在On子句中

Select * from A JOIN B on A.id=B.id;

输出结果将会是:

id     id
1      1
2      2
3      3

4

两者都允许连接“无限”表。不同之处在于,USING要求连接列具有相同的名称:

select emp.ename, dept.dname
from emp join dept using (deptno);

当连接列具有不同的名称时,ON版本也可以工作:

select emp.ename, emp2.ename manager_name
from emp join emp emp2 on (emp.mgr = emp2.empno);

我的评论关于 Oracle SQL 是错误的,虽然关于标准 SQL 是正确的。我的意思是 select * from x join y using (c1,...) 无法等同于 select * from x join y on x.c1=y.c1 and ... 因为前者有较少的列,所以你的 "the difference is" 是不正确的,但 "a difference is" 是正确的。但是在 Oracle SQL 中,在 SELECT 中使用 * 和未加点的 USING 列仍然存在差异。另外,你那句话不够清晰。并不是说这个问题要问清楚很明显。 - philipxy

1

USING子句:

SELECT * FROM COUNTRIES JOIN CITIES USING (COUNTRY)

上述查询在条件为COUNTRIES.COUNTRY等于CITIES.COUNTRY的情况下,在COUNTRIES表和CITIES表之间执行内连接。 ON子句:
SELECT * FROM COUNTRIES JOIN CITIES ON (COUNTRIES.COUNTRY = CITIES.COUNTRY)

上面的查询使用on子句执行内连接操作。

-1

On子句和Using子句都可以完成相同的工作,但如果列名相同,则应选择Using子句。否则,如果列名不同,则应选择ON子句。


这个回答不够清晰。另外,请使用标准的标点符号。 - philipxy

-1
SELECT s.SID, s.SNAME, a.CNAME, c.MAJOR
FROM STUDENT s JOIN COLLEGE c
ON s.SID = c.SID;

SELECT SID, s.SNAME, a.CNAME, a.MAJOR
FROM STUDENT s JOIN COLLEGE c
USING (SID);

USING 子句:允许通过名称指定连接键。

ON 子句允许在两个表中指定连接键的列名。


2
你只回答了问题的一半。 - Jan Doggen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接