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

LEFTJOINを含む4つのテーブルを重複せずに結合します

    LEFT JOINSが2つあります :

    • 最初の左結合は、solvedから複数の行に結合できます 。 「ジェーン」と「ルーク」がタスクを解決したと言います。
    • 左から2番目の結合は、「luke」(結合条件では「luke」)という名前のユーザーにのみ参加できます。

    あなたはまだ両方を取得します 行、「jane」は表示されません。結合条件は彼女を除外しますが、LEFT JOIN とにかく結果の行を保持し、NULL値を追加します。

    かっこを使用すると、目的を達成できます および[INNER] JOIN LEFT JOINの代わりに solvedの間 およびusers 。マニュアル:

    ネストの順序を決定するには、必要に応じて括弧を使用します。括弧がない場合は、JOIN 左から右にネストします。

    SELECT c.name AS cat_name, t.name AS task_name, u.name AS user_name
    FROM   task t
    JOIN   category c ON cat.id = t.category_id
    LEFT   JOIN
          (solved s JOIN users u ON u.id = s.user_id AND u.name = 'luke') ON s.task_id = t.id
    ORDER  BY 1, 2, 3;
    
    • テーブル名の使用users 予約語の代わりにuser

    • users.nameと仮定します 一意と定義されています または、「luke」という名前の複数のユーザーを持つことができます。

    • (task.id, users.id)の場合 solved 定義されているUNIQUE またはPRIMARY KEYDISTINCTは必要ありません まったく。

    結果のクエリは正しいだけでなく、より高速です。

    上記のクエリのSqlAlchemyバージョン: (@vanによる寄稿)
    これは、Categoryを前提としています 、Task およびUser solvedしている間、マップされたクラスです Tableのインスタンスです (コード例「多対多」に示されている関連付けテーブルのみ):

    user_name = 'luke'
    q = (session.query(Category.name, Task.name, User.name)
         .select_from(Task)
         .join(Category)
         .outerjoin(
             join(solved, User,
                  (solved.c.user_id == User.id) & (User.name == user_name),
             ))
         .order_by(Category.name, Task.name, User.name)
         )
    


    1. DevOpsがDBaaS(Database-as-a-Service)を使用してアプリケーション開発を最適化する方法

    2. Laravelからストアドプロシージャを実行する方法

    3. SQLServerの行オフセット

    4. PL-SQLのcontains()はどのように機能しますか?