Oracle USING子句的最佳实践

RAY*_*RAY 10 oracle join using natural-join

免责声明:我是开发人员,而不是DBA.

我一直是Oracle中USING子句的忠实粉丝,因为我不小心偶然发现它并且用它来代替老式的ON子句从那时起就将事实表与维度表连接起来.对我来说,它创建了一个更简洁的SQL,并生成了更简洁的结果集,没有不必要的重复列.

但是,昨天我被一位同事要求将我的所有USING条款转换为ON.我会和他核实一下,问他原因是什么.他与数据库的工作比我更密切,所以我认为他有一些很好的理由.

我没有收到他的回复(我们在不同的时区工作),但我想知道是否有关于使用"使用"条款的指导方针或最佳做法?我已经搜索了很多,但没有找到任何确定的东西.事实上,我甚至都没有在任何地方进行过很好的辩论.

有人可以对此有所了解吗?或者提供一个关于该主题的良好讨论的链接?

谢谢!

Ale*_*ole 25

你可能已经意识到这种区别,但是从文档中可以看出:

ON 条件使用该ON子句指定连接条件.这样做可以指定与WHERE子句中的任何搜索或过滤条件分开的连接条件.

USING()当您指定两个表中具有相同名称的列的等值连接时,该USING column子句指示要使用的列.仅当两个表中的连接列具有相同名称时,才能使用此子句.在此子句中,不要使用表名或表别名限定列名.

所以这些是等价的:

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

select e.ename, d.dname
from emp e join dept d on d.deptno = e.deptno;
Run Code Online (Sandbox Code Playgroud)

在很大程度上,您使用的是风格问题,但有(至少)两种情况您不能使用using:(a)当两个表中的列名不相同时,(b)当您想使用加入列:

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

select e.ename, d.dname, d.deptno
                         *
ERROR at line 1:
ORA-25154: column part of USING clause cannot have qualifier
Run Code Online (Sandbox Code Playgroud)

您当然可以放弃限定符select ..., deptno,只要您没有另一个表没有使用它连接的相同列:

select e.ename, d.dname, deptno
from emp e join dept d using (deptno) join mytab m using (empno);

select e.ename, d.dname, deptno
                         *
ERROR at line 1:
ORA-00918: column ambiguously defined
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只能选择合格的m.deptno.(好吧,这是相当人为的......).

我能看到避免的主要原因using只是一致性; 因为你有时候不能使用它,偶尔切换到on那些情况可能会有点刺耳.但同样,这更多是关于风格而不是任何深层次的技术原因.

也许你的同事只是强加(或建议)编码标准,但只有他们才会知道.如果要求您更改一些正在审核的新代码或旧代码,也不是很清楚.如果它是后者,那么无论他们更喜欢什么原因on,我认为你需要单独证明修改经过验证的代码,因为即使重新测试修改后的代码也存在引入新问题的风险 - 除了成本之外/努力涉及返工和重新测试.

尽管如此,有几件事让我想起你的问题.首先,您将on语法描述为"老式",但我不认为这是公平的 - 两者都是有效且最新的(从SQL:2011年开始我认为,但引用需要!).还有这个:

生成更简洁的结果集,没有不必要的重复列.

...我认为你正在使用它select *,否则你只需选择其中一个值,尽管有一些额外的字符用于限定符.除了即席查询和一些子查询之外,使用select *通常被认为是不好的做法(例如这里).