आपके पास दो LEFT JOINS
. हैं :
- पहला बायां जोड़
solved
. से कई पंक्तियों में शामिल हो सकता है . कहो, 'जेन' और 'ल्यूक' ने इस कार्य को हल कर दिया। - दूसरा बायां जॉइन केवल 'ल्यूक' (जॉइन कंडीशन में 'ल्यूक'!) नाम के यूजर्स से जुड़ सकता है।
आपको अभी भी दोनों मिलते हैं पंक्तियाँ, 'जेन' अभी नहीं दिखाया गया है, जुड़ने की स्थिति उसे फ़िल्टर कर देती है, लेकिन LEFT JOIN
वैसे भी परिणाम में पंक्ति को सुरक्षित रखता है और NULL मान जोड़ता है।
कोष्ठक . का उपयोग करके आप वह हासिल कर सकते हैं जो आप चाहते हैं और एक [INNER] JOIN
इसके बजाय LEFT JOINS
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
आरक्षित शब्द के बजाय <स्ट्राइक>users
स्ट्राइक> । -
मान लें कि
users.name
परिभाषित किया गया है अद्वितीय या आपके पास 'ल्यूक' नाम के एक से अधिक उपयोगकर्ता हो सकते हैं। -
अगर
(task.id, users.id)
solved
. में परिभाषित किया गया हैUNIQUE
याPRIMARY KEY
, आपकोDISTINCT
. की आवश्यकता नहीं है बिल्कुल।
परिणामी क्वेरी न केवल सही है, बल्कि तेज़ भी है।
उपरोक्त क्वेरी का SqlAlchemy संस्करण: (@van द्वारा योगदान)
यह मानता है कि Category
, Task
और users
मैप किए गए वर्ग हैं, जबकि 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)
)