2008-10-20 13 views
17

पर एक WHERE के साथ सहायता करें, मैं एक क्वेरी बनाने की कोशिश कर रहा हूं जिसमें एक कॉलम शामिल होगा जिसमें उपयोगकर्ता ने दस्तावेज़ डाउनलोड किया है या नहीं। मेरे पास निम्न कॉलम के साथ हैसडाउनलोडेड नामक एक टेबल है: आईडी, दस्तावेज़ आईडी, सदस्य आईडी। यह पता लगाना कि क्या उपयोगकर्ता ने विशिष्ट दस्तावेज़ डाउनलोड किया है, यह आसान है; लेकिन मुझे एक क्वेरी उत्पन्न करने की आवश्यकता है जहां परिणाम इस तरह दिखेगा:एक बाएं जॉइन एसक्यूएल क्वेरी

name    id 
---------------------- 
abc    NULL 
bbb    2 
ccc    53 
ddd    NULL 
eee    13 

आईडी वास्तव में महत्वपूर्ण नहीं है; मुझे क्या रूचि है कि दस्तावेज़ डाउनलोड किया गया है (क्या यह पूर्ण है या नहीं)।

SELECT Documents.name, HasDownloaded.id FROM Documents 
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id 
WHERE HasDownloaded.memberID = @memberID 

समस्या है, यह केवल मूल्यों वापस आ जाएगी एक प्रवेश HasDownloaded तालिका में निर्दिष्ट उपयोगकर्ता के लिए मौजूद है, तो:

यहाँ मेरी क्वेरी है। मैं इस सरल को रखना चाहता हूं और केवल उन दस्तावेज़ों के लिए हैसडाउनलोडेड में प्रविष्टियां हैं जो डाउनलोड की गई हैं। तो यदि उपयोगकर्ता 1 ने एबीसी, बीबीबी, और सीसीसी डाउनलोड किया है, तो मैं अभी भी आईडी के रूप में नल के रूप में परिणामस्वरूप तालिका में दिखने के लिए ddd और eee चाहता हूं। लेकिन WHERE क्लॉज केवल मुझे मूल्य देता है जिसके लिए प्रविष्टियां मौजूद हैं।

मैं एक एसक्यूएल विशेषज्ञ नहीं हूं - क्या कोई ऑपरेटर है जो मुझे यहां क्या दे सकता है? क्या मुझे एक अलग दृष्टिकोण लेना चाहिए? या यह असंभव है?

उत्तर

35

स्थिति की स्थिति में WHERE खंड में स्थिति को ले जाएं।

SELECT Documents.name, HasDownloaded.id FROM Documents 
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id 
    AND HasDownloaded.memberID = @memberID 

यह जब भी आप क्या अन्यथा कहां खंड होगा में एक छोड़ दिया में शामिल होने के एड तालिका देखें करना चाहते हैं आवश्यक है।

+1

उत्कृष्ट! यही वह है जिसे मैं ढूंढ रहा था। – ine

+1

संपादित करें: मेरे स्वयं के प्रश्न का उत्तर दें। मैं एक महान स्पष्टीकरण खोजने में सक्षम था कि यह सच क्यों है। http://weblogs.sqlteam.com/jeffs/archive/2007/05/14/criteria-on-outer-joined-tables.aspx –

4
WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId 

ऐसा करने का सामान्य तरीका होगा। कुछ इसे करने के लिए छोटा होगा:

WHERE COALESCE(HasDownloaded.memberId, @memberId) = @memberId 

आप के रूप में मैट बी से पता चलता है, यह में कर सकते हैं अपने में शामिल हों हालत - लेकिन मुझे लगता है कि और अधिक लोगों को भ्रमित करने के लिए संभावना है। यदि आप समझ में नहीं आ रहे हैं कि इसे जॉइन क्लॉज कामों में क्यों ले जाया गया है, तो मैं दृढ़ता से सुझाव देना चाहता हूं कि इससे दूर रहें।

3

@ मार्क: मैं समझता हूं कि जॉइन सिंटैक्स क्यों काम करता है, लेकिन चेतावनी के लिए धन्यवाद। मुझे लगता है कि आपका सुझाव अधिक सहज है। मैं यह देखने के लिए उत्सुक था कि कौन सा अधिक कुशल था। तो मैं एक त्वरित परीक्षण भाग गया (यह नहीं बल्कि साधारण, मुझे डर लग रहा है, केवल 14 पंक्तियों और 10 प्रयत्नों खत्म हो गया था):

शामिल हों हालत में:

AND HasDownloaded.memberID = @memberID 
  • ग्राहक प्रसंस्करण समय: 4.6
  • कुल निष्पादन समय: सर्वर पर 35.5
  • प्रतीक्षा समय उत्तर: 30,9

कहां खंड में:

WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId 
  • ग्राहक प्रसंस्करण समय: 7.7
  • कुल निष्पादन समय: सर्वर पर 27.7
  • प्रतीक्षा समय उत्तर: 22।0

ऐसा लगता है कि WHERE क्लॉज कभी-कभी थोड़ा अधिक कुशल है। दिलचस्प! एक बार फिर, आपकी मदद के लिए आप दोनों को धन्यवाद।

संबंधित मुद्दे