आपके पास दो 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)
)