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 KEY
、DISTINCT
は必要ありません まったく。
結果のクエリは正しいだけでなく、より高速です。
上記のクエリの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)
)