11

免責事項: 私は開発者であり、DBA ではありません。

私は、偶然 Oracle の USING 句に出くわして以来、この句の大ファンであり、昔ながらの ON 句の代わりにそれを使用して、ファクト テーブルとディメンション テーブルを結合してきました。私にとっては、はるかに簡潔な SQL が作成され、不要な重複列のない、より簡潔な結果セットが生成されます。

しかし、昨日同僚から、すべての USING 句を ON に変換するように依頼されました。私は彼に確認し、彼の理由を尋ねます。彼は私よりもはるかにデータベースに密接に取り組んでいるので、彼にはいくつかの正当な理由があると思います。

彼から返事はありませんが (私たちは異なるタイムゾーンで働いています)、「using」句の使用に関するガイドラインやベスト プラクティスはあるのでしょうか? 私はかなりグーグルで調べましたが、決定的なものに出くわしていません。実際、私はどこでも良い議論さえしていません。

誰かがこれに光を当てることができますか? または、トピックに関する適切なディスカッションへのリンクを提供してください。

ありがとうございました!

4

3 に答える 3

27

あなたはおそらくすでに違いを認識していますが、ドキュメントから:

ON condition句を使用してON、結合条件を指定します。WHEREこれにより、句内の検索条件またはフィルタ条件とは別に結合条件を指定できます。

USING ( column )両方のテーブルで同じ名前を持つ列の等結合を指定する場合、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;

どちらを使用するかはスタイルの問題ですが、(少なくとも) を使用できない状況が 2 つありますusing。(a) 2 つのテーブルで列名が同じでない場合、および (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

select ..., deptnoもちろん、それを使用して結合されていない同じ列を持つ別のテーブルがない限り、修飾子 and をそのままにしておくことができます:

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

その場合、修飾されたのみm.deptnoを選択できます。(OK、これはかなり不自然です...)。

回避する主な理由usingは、一貫性です。使えないこともあるので、onそのような状況で時々切り替えるのは少し耳障りかもしれません. しかし、それは深い技術的な理由よりもスタイルに関するものです。

おそらく、あなたの同僚は単にコーディング標準を課す (または提案する) だけですが、それを知っているのは同僚だけです。また、レビュー中の新しいコードを変更するよう求められているのか、それとも古いコードを変更するよう求められているのかも明確ではありません。後者の場合、彼らが好む理由に関係なく、on変更されたコードが再テストされた場合でも新しい問題が発生するリスクがあるため、証明されたコードを変更するための別の正当化を取得する必要があると思います-コストは別として/やり直しと再テストに伴う労力。

ただし、あなたの質問についていくつかのことが気になります。最初に、on構文を「昔ながら」と説明していますが、それは公平ではないと思います-両方とも有効で最新です(SQL:2011の時点では、私は思うが、引用が必要です!)。この:

不要な重複列がない、より簡潔な結果セットを生成します。

...これは、 を使用していることを示唆していると思います。select *それ以外の場合は、修飾子にいくつかの余分な文字がありますが、値の1つを選択するだけです。アドホッククエリと一部のサブクエリ以外では、使用select *は一般的に悪い習慣と見なされます (ここでは例を示します)。

于 2013-04-23T07:51:12.223 に答える
2

関連する質問

主な違いは構文にあるようです。列はUSING結合でマージされます。

いずれの場合も、これは特定のテーブルから結合された列の値にアクセスできないことを意味します。実際には、一部の SQL はコンパイルされません。次に例を示します。

SQL> WITH t AS (SELECT 1 a, 2 b, 3 c FROM dual),
  2       v AS (SELECT 1 a, 2 b, 3 c FROM dual)
  3  SELECT t.* FROM t JOIN v USING (a);

SELECT t.* FROM t JOIN v USING (a)
         ^    
ORA-25154: column part of USING clause cannot have qualifier

外部結合では、これは外部テーブルの値にアクセスできないことを意味します。

SQL> WITH t AS (SELECT 1 a, 2 b, 3 c FROM dual),
  2       v AS (SELECT NULL a, 2 b, 3 c FROM dual)
  3  SELECT * FROM t LEFT JOIN v USING (a)
  4   WHERE v.a IS NULL;

 WHERE v.a IS NULL
         ^
ORA-25154: column part of USING clause cannot have qualifier

USINGこれは、句を使用したこの結合防止構文に相当するものがないことを意味します。

SQL> WITH t AS (SELECT 1 a, 2 b, 3 c FROM dual),
  2       v AS (SELECT NULL a, 2 b, 3 c FROM dual)
  3  SELECT * FROM t LEFT JOIN v ON v.a = t.a
  4   WHERE v.a IS NULL;

         A          B          C A          B          C
---------- ---------- ---------- - ---------- ----------
         1          2          3  

これとは別に、SQLが有効になると、違いはわかりません。

ただし、この構文はあまり使用されていないように見えるためUSING、特に ANSI SQL が導入された初期のバージョンで、句のみに影響する特定のバグがあったとしても驚かないでしょう。これを確認できる MOS に関する情報は見つかりませんでした。その理由の 1つは、 USINGという言葉がバグの説明に広く使われているためです。

この機能を使用しない理由がバグによるものである場合、立証責任は同僚にあるように私には思えます: バグにパッチが適用されると、最終的に禁止が解除されるように、バグを参照/文書化する必要があります (データベースアップグレード...)。

理由が見かけ上またはコーディング規約の一部である場合は、それも文書化する必要があります。

于 2013-04-23T07:51:50.057 に答える