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

結合を使用してPostgreSQLの異なるテーブルのデータを結合する


    はじめに

    関連データを個別のテーブルに分割することは、一貫性、柔軟性、および特定のタイプのパフォーマンスの観点から有益な場合があります。ただし、関連情報が複数のテーブルにまたがっている場合でも、レコードを再統合するための合理的な方法が必要です。

    リレーショナルデータベースでは、参加 共通のフィールド値に基づいて、2つ以上のテーブルのレコードを組み合わせる方法を提供します。異なるタイプの結合は、一致しない行の処理方法に応じて異なる結果を達成できます。このガイドでは、PostgreSQLが提供するさまざまなタイプの結合と、それらを使用して複数のソースからのテーブルデータを結合する方法について説明します。



    結合とは何ですか?

    つまり、参加 複数のテーブルのデータを表示する方法です。これは、特定の列の一致する値に基づいて、さまざまなソースからのレコードをつなぎ合わせることによって行われます。結果の各行は、同じ値を持つ各テーブルの1つ以上の列に基づいて、最初のテーブルのレコードと2番目のテーブルの行を組み合わせたもので構成されます。

    結合の基本的な構文は次のようになります。

    SELECT    *FROM    <first_table><join_type> <second_table>    <join_condition>;

    結合では、結果の各行は、最初のテーブルのすべての列と、それに続く2番目のテーブルのすべての列を含めることによって作成されます。 SELECT クエリの一部を使用して、表示する正確な列を指定できます。

    比較に使用される列の値が一意でない場合は、元のテーブルから複数の行を作成できます。たとえば、値が「red」の2つのレコードを持つ最初のテーブルから比較されている列があるとします。これと一致するのは、その値を持つ3つの行を持つ2番目のテーブルの列です。結合により、達成可能なさまざまな組み合わせを表すその値に対して6つの異なる行が生成されます。

    結合のタイプと結合条件によって、表示される各行がどのように構成されるかが決まります。これは、各テーブルの行が実行する行と実行しない行に影響を与えます。 参加条件が一致している。

    便宜上、多くの結合は、1つのテーブルの主キーを2番目のテーブルの関連する外部キーと一致させます。主キーと外部キーは、一貫性の保証を維持するためにデータベースシステムによってのみ使用されますが、それらの関係により、結合条件の候補として適していることがよくあります。



    さまざまな種類の結合

    さまざまなタイプの結合が利用可能であり、それぞれが異なる結果を生成する可能性があります。各タイプがどのように構成されているかを理解すると、さまざまなシナリオに適したタイプを判断するのに役立ちます。


    内部参加

    デフォルトの結合は内部結合と呼ばれます 。 PostgreSQLでは、これはINNER JOINのいずれかを使用して指定できます。 または単にJOIN

    これは、内部結合の構文を示す典型的な例です。

    SELECT    *FROM    table_1[INNER] JOIN table_2    ON table_1.id = table_2.table_1_id;

    内部結合は、各テーブルの行を組み合わせて作成された行のみを表示するため、最も制限の厳しいタイプの結合です。他のテーブルに一致する対応するものがなかった構成テーブルの行は、結果から削除されます。たとえば、最初のテーブルの比較列に「青」の値があり、2番目のテーブルにその値のレコードがない場合、その行は出力から抑制されます。

    結果をコンポーネントテーブルのベン図として表す場合、内部結合を使用すると、2つの円の重なり合う領域を表すことができます。いずれかのテーブルにのみ存在する値は表示されません。



    左結合

    左結合は、内部結合で見つかったすべてのレコードに加えて、すべての一致しないを表示する結合​​です。 最初のテーブルの行。 PostgreSQLでは、これはLEFT OUTER JOINとして指定できます。 または、LEFT JOINとして 。

    左結合の基本的な構文は、次のパターンに従います。

    SELECT    *FROM    table_1LEFT JOIN table_2    ON table_1.id = table_2.table_1_id;

    左結合は、最初に内部結合を実行して、両方のテーブルの一致するすべてのレコードから行を構築することによって構築されます。その後、最初のテーブルの一致しないレコードも含まれます。結合の各行には両方のテーブルの列が含まれるため、一致しない列はNULLを使用します 2番目のテーブルのすべての列の値として。

    結果をコンポーネントテーブルのベン図として表す場合、左結合を使用すると、左の円全体を表すことができます。 2つの円の交点で表される左側の円の部分には、右側の表によって補足される追加のデータがあります。



    右参加

    右結合とは、内部結合で見つかったすべてのレコードに加えて、すべての不一致を表示する結合​​です。 2番目のテーブルの行。 PostgreSQLでは、これはRIGHT OUTER JOINとして指定できます。 または単にRIGHT JOINとして 。

    右結合の基本的な構文は、次のパターンに従います。

    SELECT    *FROM    table_1RIGHT JOIN table_2    ON table_1.id = table_2.table_1_id;

    右結合は、最初に内部結合を実行して、両方のテーブルの一致するすべてのレコードから行を構築することによって構築されます。その後、2番目のテーブルの一致しないレコードも含まれます。結合の各行には両方のテーブルの列が含まれるため、一致しない列はNULLを使用します 最初のテーブルのすべての列の値として。

    結果をコンポーネントテーブルのベン図として表す場合、右結合を使用すると、右の円全体を表すことができます。 2つの円の交点で表される右の円の部分には、左の表で補足された追加のデータがあります。



    完全参加

    完全結合とは、内部結合で見つかったすべてのレコードに加えて、すべての不一致を表示する結合​​です。 両方のコンポーネントテーブルの行。 PostgreSQLでは、これはFULL OUTER JOINとして指定できます。 または、FULL JOINとして 。

    完全結合の基本的な構文は、次のパターンに従います。

    SELECT    *FROM    table_1FULL JOIN table_2    ON table_1.id = table_2.table_1_id;

    完全結合は、最初に内部結合を実行して、両方のテーブルの一致するすべてのレコードから行を構築することによって構築されます。その後、両方のテーブルからの一致しないレコードも含まれます。結合の各行には両方のテーブルの列が含まれるため、一致しない列はNULLを使用します 比類のない他のテーブルのすべての列の値として。

    結果をコンポーネントテーブルのベン図として表す場合、完全結合を使用すると、両方のコンポーネント円を完全に表すことができます。 2つの円の交点には、各コンポーネントテーブルによって提供される値があります。重なり合う領域の外側の円の部分には、NULLを使用して、それらが属するテーブルの値が含まれます。 他のテーブルにある列に入力します。



    クロスジョイン

    CROSS JOINと呼ばれる特別な結合 もご利用いただけます。クロス結合は、各テーブルの行が互いに一致するかどうかを判断するために比較を使用しません。代わりに、最初のテーブルの各行を2番目のテーブルの各行に追加するだけで結果が作成されます。

    これにより、2つ以上のテーブルの行のデカルト積が生成されます。実際、このスタイルの結合は、各テーブルの行を無条件に結合します。したがって、各テーブルに3つの行がある場合、結果のテーブルには、両方のテーブルのすべての列を含む9つの行が含まれます。

    たとえば、t1というテーブルがある場合 t2というテーブルと組み合わせる 、それぞれにr1の行があります 、r2 、およびr3 、結果は次のように組み合わされた9行になります:

    t1.r1 + t2.r1t1.r1 + t2.r2t1.r1 + t2.r3t1.r2 + t2.r1t1.r2 + t2.r2t1.r2 + t2.r3t1.r3 + t2.r1t1.r3 + t2.r2t1.r3 + t2.r3


    自己参加

    自己結合は、テーブルの行をそれ自体と結合する結合です。これがどのように役立つかはすぐにはわからないかもしれませんが、実際には多くの一般的なアプリケーションがあります。

    多くの場合、テーブルは、相互に関連して複数の役割を果たすことができるエンティティを記述します。たとえば、peopleのテーブルがある場合 、各行にmotherが含まれる可能性があります 他のpeopleを参照する列 テーブルで。自己結合を使用すると、テーブルの2番目のインスタンスを、これらの値が一致する最初のインスタンスに結合することで、これらの異なる行をつなぎ合わせることができます。

    自己結合は同じテーブルを2回参照するため、参照を明確にするためにテーブルエイリアスが必要です。たとえば、上記の例では、peopleの2つのインスタンスを結合できます。 エイリアスを使用したテーブルpeople AS children およびpeople AS mothers 。これにより、結合条件を定義するときに参照するテーブルのインスタンスを指定できます。

    別の例を次に示します。今回は、従業員とマネージャーの関係を表しています。

    SELECT    *FROM    people AS employeeJOIN people AS manager    ON employee.manager_id = manager.id;



    参加条件

    テーブルを結合する場合、結合条件によって、行をどのように照合して複合結果を形成するかが決まります。基本的な前提は、各テーブルで、その行で結合が発生するために一致する必要がある列を定義することです。


    ON 条項

    テーブル結合の条件を定義する最も標準的な方法は、ONを使用することです。 句。 ON 句は等号を使用して、結合がいつ発生するかを決定するために比較される各テーブルの正確な列を指定します。 PostgreSQLは、提供された列を使用して、各テーブルの行をつなぎ合わせます。

    ON 句は最も冗長ですが、使用可能な結合条件の中で最も柔軟です。結合される各テーブルの列名がどの程度標準化されているかに関係なく、特異性があります。

    ONの基本構文 句は次のようになります:

    SELECT    *FROM    table1JOIN    table2ON    table1.id = table2.ident;

    ここでは、table1の行 およびtable2 idはいつでも参加します table1の列 identと一致します table2の列 。内部結合が使用されているため、結果には結合された行のみが表示されます。クエリはワイルドカード*を使用するため 文字の場合、両方のテーブルのすべての列が表示されます。

    これは、両方のid table1の列 およびident table2の列 結合条件を満たすため、正確な値は同じですが、が表示されます。 SELECTに表示したい正確な列を呼び出すことで、この重複を回避できます。 列リスト。



    USING 条項

    USING 句は、ONの条件を指定するための省略形です。 比較される列が両方のテーブルで同じ名前である場合に使用できる句。 USING 句は、比較する必要のある共有列名のリストを括弧で囲んで取得します。

    USINGの一般的な構文 句は次の形式を使用します:

    SELECT    *FROM    table1JOIN    table2USING    (id, state);

    この結合はtable1を組み合わせたものです table2を使用 両方のテーブルが共有する2つの列の場合(id およびstate )それぞれに一致する値があります。

    この同じ結合は、ONを使用してより詳細に表現できます。 このように:

    SELECT    *FROM    table1JOIN    table2ON    table1.id = table2.id AND table1.state = table2.state;

    上記の両方の結合により、同じデータが存在する状態で同じ行が作成されますが、表示はわずかに異なります。 ON 句には、両方のテーブルのすべての列、USINGが含まれます 句は重複する列を抑制します。したがって、2つの別々のidがある代わりに 列と2つの別々のstate 列(テーブルごとに1つ)の場合、結果には共有列のそれぞれが1つだけ含まれ、その後にtable1によって提供される他のすべての列が続きます。 およびtable2



    NATURAL 条項

    NATURAL 句は、USINGの冗長性をさらに減らすことができるもう1つの省略形です。 句。 NATURAL joinはanyを指定しません 照合する列。代わりに、PostgreSQLは、各データベースに一致する列があるすべての列に基づいてテーブルを自動的に結合します。

    NATURALの一般的な構文 join句は次のようになります:

    SELECT    *FROM    table1NATURAL JOIN    table2;

    table1と仮定します およびtable2 どちらにもidという名前の列があります 、state 、およびcompany 、上記のクエリは、ONを使用したこのクエリと同等です。 条項:

    SELECT    *FROM    table1JOIN    table2ON    table1.id = table2.id AND table1.state = table2.state AND table1.company = table2.company;

    そして、USINGを使用したこのクエリ 条項:

    SELECT    *FROM    table1JOIN    table2USING    (id, state, company);

    USINGのように 句、NATURAL 句は重複する列を抑制するため、結果には結合された各列のインスタンスが1つだけ存在します。

    NATURAL 句はクエリの冗長性を減らす可能性があるため、使用するときは注意が必要です。テーブルの結合に使用される列は自動的に計算されるため、コンポーネントテーブルの列が変更された場合、新しい結合条件によって結果が大きく異なる可能性があります。




    条件とWHEREを結合します 条項

    結合条件は、WHEREを使用してデータの行をフィルタリングするために使用される比較と多くの特性を共有します 条項。どちらの構成も、考慮される行に対してtrueと評価される必要がある式を定義します。このため、WHEREに追加の比較を含めることの違いが常に直感的であるとは限りません。 結合句自体の中でそれらを定義するのではなく構築します。

    結果として生じる違いを理解するために、PostgreSQLがクエリのさまざまな部分を処理する順序を確認する必要があります。この場合、結合条件の述語が最初に処理されて、メモリ内に仮想結合テーブルが構築されます。この段階の後、WHERE内の式 結果の行をフィルタリングするために句が評価されます。

    例として、customerという2つのテーブルがあるとします。 およびorder 一緒に参加する必要があります。 customer.idを照合して、2つのテーブルを結合します。 order.customer_idの列 桁。さらに、orderの行にも関心があります product_idを持つテーブル 12345の。

    上記の要件を考えると、私たちが気にする2つの条件があります。ただし、これらの条件を表現する方法によって、受け取る結果が決まります。

    まず、LEFT JOINの結合条件として両方を使用しましょう。 :

    SELECT    customer.id AS customer_id,    customer.name,    order.id AS order_id,    order.product_idFROM    customerLEFT JOIN    orderON    customer.id = order.customer_id AND order.product_id = 12345;

    結果は次のようになる可能性があります:

     customer_id |   name   | order_id | product_id ------------+----------+----------+------------        4380 | Acme Co  |      480 |      12345        4380 | Acme Co  |      182 |      12345         320 | Other Co |      680 |      12345        4380 | Acme Co  |          |         320 | Other Co |          |          20 | Early Co |          |        8033 | Big Co   |          |(7 rows)

    PostgreSQLは、次の操作を実行することでこの結果に到達しました。

    1. customerの任意の行を結合します orderのテーブル テーブルここで:
      • customer.id order.customer_idと一致します 。
      • order.product_id 12345に一致
    2. 左結合を使用しているため、一致しないを含めます。 左側のテーブルの行(customer )、右側のテーブルから列をパディングします(order )with NULL 値。
    3. SELECTにリストされている列のみを表示します 列の仕様。

    その結果、結合されたすべての行が、探している両方の条件に一致します。ただし、左結合により、PostgreSQLには、結合条件を満たさなかった最初のテーブルの行も含まれます。これにより、クエリの明確な意図に従わないように見える「残りの」行が生成されます。

    2番目のクエリ(order.product_id =12345)からWHERE 句、結合条件として含める代わりに、異なる結果が得られます:

    SELECT    customer.id AS customer_id,    customer.name,    order.id AS order_id,    order.product_idFROM    customerLEFT JOIN    orderON    customer.id = order.customer_idWHERE    order.product_id = 12345;

    今回は、3行のみが表示されます:

     customer_id |   name   | order_id | product_id ------------+----------+----------+------------        4380 | Acme Co  |      480 |      12345        4380 | Acme Co  |      182 |      12345         320 | Other Co |      680 |      12345(3 rows)

    比較が実行される順序が、これらの違いの理由です。今回、PostgreSQLは次のようにクエリを処理します:

    1. customerの任意の行を結合します orderのテーブル customer.idのテーブル order.customer_idと一致します 。
    2. 左結合を使用しているため、一致しないを含めます。 左側のテーブルの行(customer )、右側のテーブルから列をパディングします(order )with NULL 値。
    3. WHEREを評価します order.product_idの値として12345を持たない行を削除する句 列。
    4. SELECTにリストされている列のみを表示します 列の仕様。

    今回は、左結合を使用していますが、WHERE 句は、正しいproduct_idなしですべての行を除外することにより、結果を切り捨てます。 。一致しない行にはproduct_idが含まれるため NULLに設定 、これにより、左結合によって入力された一致しない行がすべて削除されます。また、この2回目のチェックに合格しなかった結合条件に一致した行もすべて削除されます。

    PostgreSQLがクエリを実行するために使用する基本的なプロセスを理解すると、データを操作するときに、作成は簡単ですがデバッグが難しいミスを回避するのに役立ちます。



    結論

    このガイドでは、結合によってリレーショナルデータベースがさまざまなテーブルのデータを組み合わせて、より価値のある回答を提供する方法について説明しました。 PostgreSQLがサポートするさまざまな結合、各タイプがその結果をアセンブルする方法、および特定の種類の結合を使用する場合に何が期待できるかについて説明しました。その後、結合条件を定義するさまざまな方法を検討し、結合とWHEREの間の相互作用を調べました。 条項は驚きにつながる可能性があります。

    結合は、リレーショナルデータベースを非常に多くの異なるタイプのクエリを処理するのに十分なほど強力かつ柔軟にするための重要な部分です。論理的な境界を使用してデータを整理しながら、ケースバイケースで斬新な方法でデータを再結合できるため、PostgreSQLのようなリレーショナルデータベースは非常に多様性があります。テーブル間でこのスティッチングを実行する方法を学ぶことで、より複雑なクエリを作成し、データベースに依存してデータの完全な画像を作成できるようになります。




    1. ONUPDATEで次のORA-00907エラーが発生する

    2. SQLServerのデフォルトの文字エンコード

    3. SQLiteの既存のテーブルに列を追加する

    4. 2Oracleの日時値から秒を返す関数