Bạn có hai LEFT JOINS :
- Kết nối đầu tiên bên trái có thể kết hợp với nhiều hàng từ
solved. Giả sử, 'jane' và 'luke' đã giải quyết xong công việc. - Tham gia thứ hai bên trái chỉ có thể tham gia với những người dùng có tên 'luke' ('luke' trong điều kiện tham gia!).
Bạn vẫn nhận được cả hai hàng, 'jane' chỉ không được hiển thị, điều kiện tham gia lọc cô ấy ra, nhưng LEFT JOINS Vẫn giữ nguyên hàng trong kết quả và thêm các giá trị NULL.
Bạn có thể đạt được những gì hiện tại bằng cách sử dụng dấu ngoặc đơn và một [INNER] JOIN thay vì LEFT JOINS giữa solved và users . Hướng dẫn sử dụng:
Sử dụng dấu ngoặc đơn nếu cần thiết để xác định thứ tự lồng vào nhau. Trong dấu ngoặc đơn,
JOINs lồng nhau từ trái sang phải.
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;
-
Sử dụng tên bảng
usersthay vì từ dành riêng.user -
Giả sử rằng
users.nameđược xác định duy nhất hoặc bạn có thể có nhiều người dùng được đặt tên là 'luke'. -
Nếu
(task.id, users.id)trongsolvedđược định nghĩaUNIQUEhoặcPRIMARY KEY, bạn không cầnDISTINCTở tất cả.
Truy vấn kết quả không chỉ chính xác mà còn nhanh hơn.
Phiên bản SqlAlchemy của truy vấn trên: (đóng góp bởi @van)
Điều này giả định rằng Category , Task và User là các lớp được ánh xạ, trong khi solved là bản sao của Table (chỉ là một bảng liên kết như được hiển thị trong ví dụ mã Nhiều đến Nhiều):
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)
)