sql >> データベース >  >> RDS >> Oracle

自己結合と内部結合

    SELECTステートメント内のすべてのテーブルを独自のデータセットを表すものと考えると便利です。

    条件を適用する前に、各データセットが完全であると考えることができます(たとえば、テーブル全体)。

    結合は、これらのデータセットを改良して、本当に必要な情報を見つけるためのいくつかの方法の1つにすぎません。

    データベーススキーマは特定の関係(主キー<->外部キー)を念頭に置いて設計されている場合がありますが、これらの関係は実際には特定のクエリのコンテキストにのみ存在します。クエリライターは、必要なものを必要なものに関連付けることができます。この例は後で説明します...

    INNER JOINは、2つのテーブルを相互に関連付けます。多くの場合、複数のテーブルをチェーン化するために、1つのクエリに複数のJOIN操作があります。必要なだけ複雑になる可能性があります。簡単な例として、次の3つの表を考えてみましょう...

    STUDENT
    
    | STUDENTID | LASTNAME | FIRSTNAME |
    ------------------------------------
          1     |  Smith   |   John
          2     |  Patel   |  Sanjay
          3     |   Lee    |  Kevin
          4     |  Jackson |  Steven
    
    ENROLLMENT
    
    | ENROLLMENT ID | STUDENTID | CLASSID |
    ---------------------------------------
            1       |     2     |    3
            2       |     3     |    1
            3       |     4     |    2
    
    CLASS
    
    | CLASSID | COURSE | PROFESSOR |
    --------------------------------
         1    | CS 101 |   Smith
         2    | CS 201 |  Ghandi
         3    | CS 301 |  McDavid
         4    | CS 401 |  Martinez
    

    STUDENTテーブルとCLASSテーブルは、ENROLLMENTテーブルを介して相互に関連するように設計されています。この種のテーブルは、ジャンクションテーブルと呼ばれます。 。

    すべての学生とそれらが登録されているクラスを表示するクエリを作成するには、2つを使用します。 内部結合...

    SELECT stud.LASTNAME, stud.FIRSTNAME, class.COURSE, class.PROFESSOR
    FROM STUDENT stud
    INNER JOIN ENROLLMENT enr
        ON stud.STUDENTID = enr.STUDENTID
    INNER JOIN CLASS class
        ON class.CLASSID = enr.CLASSID;
    

    上記をよく読んでください。何が起こっているかがわかります。見返りとして得られるのは、次のデータセットです...

     | LASTNAME | FIRSTNAME | COURSE | PROFESSOR |
     ---------------------------------------------
         Patel  |   Sanjay  | CS 301 |  McDavid
          Lee   |   Kevin   | CS 101 |   Smith
        Jackson |  Steven   | CS 201 |  Ghandi
    

    JOIN句を使用して、3つのテーブルすべてのデータセットを互いに一致するもののみに制限しました。 「一致」は、オンを使用して定義されます 条項。このクエリを実行した場合、しないことに注意してください。 これらのIDは一致(この場合はENROLLMENTテーブル)に存在しないため、CLASSテーブルのCLASSID4行またはSTUDENTテーブルのSTUDENTID1行を参照してください。 「LEFT」/「RIGHT」/「FULLOUTER」JOINを調べて、それを少し異なる方法で機能させる方法の詳細を確認してください。

    以前の「関係」についての私のコメントによると、理由はありませんことに注意してください STUDENTテーブルとCLASSテーブルに関連するクエリをLASTNAME列とPROFESSOR列で直接実行できなかった理由。これらの2つの列はデータ型が一致しているので、よく見てください。それらには共通の価値さえあります!これはおそらく、見返りとして取得するための奇妙なデータセットになります。私のポイントは、それは可能であり、データ内の興味深い接続のために将来どのようなニーズがあるかわからないということです。データベースの設計を理解しますが、「関係」を無視できないルールとは考えないでください。

    それまでの間...SELFJOINS!

    次の表を検討してください...

    PERSON
    
    | PERSONID | FAMILYID |  NAME  |
    --------------------------------
          1    |     1    |  John
          2    |     1    | Brynn
          3    |     2    | Arpan
          4    |     2    | Steve
          5    |     2    |  Tim
          6    |     3    | Becca
    

    知っているすべての人と同じ家族の人のデータベースを作成したいと思った場合は、次のようになります。

    たとえば、PERSONID 4などの1人を返却したい場合は、次のように記述します...

    SELECT * FROM PERSON WHERE PERSONID = 4;
    

    彼がFAMILYID2の家族に属していることがわかります。次に、すべてを見つけます。 あなたが書くだろう彼の家族の人の...

    SELECT * FROM PERSON WHERE FAMILYID = 2;
    

    完了しました!もちろん、SQLは、SELF JOINを使用して、1つのクエリでこれを実現できます。

    自己参加の必要性を実際に引き起こすもの これは、テーブルに一意の列(PERSONID)と、一種の「カテゴリ」(FAMILYID)として機能する列が含まれていることです。この概念はカーディナリティと呼ばれます この場合、 1対多または1:Mを表します 関係。 1つしかありません 各の しかし、多くがあります 家族で 。

    ですから、私たちが返したいのはすべてです 1つの場合は家族のメンバーの 家族のPERSONIDのメンバーは知られています...

    SELECT fam.*
    FROM PERSON per
    JOIN PERSON fam
        ON per.FamilyID = fam.FamilyID
    WHERE per.PERSONID = 4;
    

    これがあなたが得るものです...

    | PERSONID | FAMILYID |  NAME  |
    --------------------------------
          3    |     2    | Arpan
          4    |     2    | Steve
          5    |     2    |  Tim
    

    いくつかのことに注意しましょう。 自己参加という言葉 どこにも発生しないでください。これは、自己参加が 単なる概念です。 参加という言葉 上記のクエリでは、 LEFT JOINである可能性があります 代わりに、さまざまなことが起こったでしょう。 自己参加のポイント 同じテーブルを2回使用しているということです。

    以前のデータセットのsoapboxについて考えてみましょう。ここでは、PERSONテーブルのデータセットから2回開始しました。どちらのインスタンスも データセットの一部は、特に影響がない限り、もう一方に影響します。

    クエリの最後から始めましょう。 あたり データセットは、PERSONID =4の行のみに制限されています。テーブルがわかっていると、正確に1行が返されます。その行のFAMILYID列の値は2です。

    ON句では、 famを制限しています。 FAMILYIDの値が1つ以上に一致する行のみへのデータセット(この時点ではまだPERSONテーブル全体です) あたりのFAMILYIDの データセット。話し合ったように、あたり データセットには1つの行しかないため、1つのFAMILYID値があります。したがって、ファム データセットには、FAMILYID=2の行のみが含まれるようになりました。

    最後に、クエリの先頭で、 famのすべての行を選択しています。 データセット。

    出来上がり! 1つに2つのクエリ。

    結論として、内部参加 は、いくつかの種類のJOIN操作の1つです。 強く LEFT、RIGHT、およびFULL OUTER JOIN(まとめて OUTER JOIN と呼ばれます)をさらに読むことをお勧めします。 )。私は個人的に、OUTER JOINの知識が弱いために仕事の機会を逃し、それを二度と起こさせません!

    自分の参加 テーブルをそれ自体に関連付けるJOIN操作です。そのテーブルをそれ自体に結合することを選択する方法では、内部結合を使用できます。 またはOUTERJOIN。 SELF JOINを使用することに注意してください 、SQLエンジンを混乱させないために、必須 テーブルエイリアス(famとperを上から。クエリに適したものを作成)を使用するか、さまざまなバージョンを区別する方法がありません。 同じテーブルの。

    違いを理解したので、心を広く開いて、1つのクエリにすべての異なる種類のJOINを一度に含めることができることに気付きました。必要なデータと、それを取得するためにクエリをどのようにねじったり曲げたりする必要があるかが問題になります。 1つのクエリを実行し、そのクエリの結果を取得して別のクエリの入力として使用していることに気付いた場合は、おそらく JOINを使用できます。 代わりに1つのクエリにします。

    SQLを試してみるには、W3Schools.com にアクセスしてみてください。 そこにはローカルに保存されたデータベースがあり、さまざまな方法で相互に関連するように設計された一連のテーブルがあり、データで満たされています。必要なものをすべてCREATE、DROP、INSERT、UPDATE、およびSELECTして、いつでもデータベースをデフォルトに戻すことができます。さまざまなトリックを試すために、あらゆる種類のSQLを試してみてください。私自身、そこで多くのことを学びました。

    少し言葉が多かったら申し訳ありませんが、SQLを学び始めたとき、私はJOINの概念に個人的に苦労し、他の複雑な概念をたくさん使って概念を説明しました。時々一番下から始めるのがベストです。

    お役に立てば幸いです。 JOINをバックポケットに入れることができれば、SQLを使って魔法をかけることができます!

    クエリをお楽しみください!



    1. データディクショナリレポートツール

    2. SQLServerに展開されたSSISパッケージをVisualStudio2008にコピーして戻す

    3. コマンドラインからのsqlplusステートメント

    4. Oracle Deleteステートメント:カスケード削除によって削除された行数