2015-02-18 4 views
6

आज मैंने कुछ और जटिल MySQL प्रश्नों का प्रयास किया है और मैंने देखा है कि MySQL की बाएं जॉइन WHERE क्लॉज के साथ काम नहीं कर रही है। मेरा मतलब है, यह कुछ रिकॉर्ड वापस करता है लेकिन यह उन लोगों को वापस नहीं करता है जो दाईं तरफ खाली हैं।क्यों MySQL की बाएं जॉइन WHERE क्लॉज के साथ "NULL" रिकॉर्ड लौट रही है?

उदाहरण के लिए मान लीजिए कि हम तालिकाओं के लिए मिल गया है चलो:

albums         ; albums_rap 
    id artist  title   tracks ; id artist title   rank 
---- -------- ---------- --------------- ; ---- --------- ----- -------------- 
    1 John Doe  Mix CD    20 ;  3 Mark  CD #7   15 
    2 Mark   CD #7    35 ;

और जब मैं इस क्वेरी चलाने: मैं मिल

SELECT 
    t1.artist as artist, 
    t1.title as title, 
    t1.tracks as tracks, 
    t2.rank as rank, 
FROM 
    albums as t1 
LEFT JOIN 
    albums_rap as t2 
ON 
    t1.artist LIKE t2.artist 
AND 
    t1.title LIKE t2.title 
WHERE 
    t2.rank != 17 

इस:

artist title tracks rank 
------ ----- ------ ----- 
Mark CD #7  35 15

लेकिन जब मैं इस क्वेरी में "ANDER" के साथ "WHERE" को प्रतिस्थापित करें I:

artist  title tracks rank 
------ --------- ------ ----- 
Mark  CD #7  35 15 
John Doe Mix CD  20 NULL

क्यों पहले एक "शून्य" के साथ रिकॉर्ड नहीं लौटा रहा है (शून्य 17 के बराबर नहीं है ...)

मुझे आशा है कि आप समझ में आ रहा क्या मतलब है और आप किसी भी तरह मुझे अंतर समझाएंगे। मेरी बुरी अंग्रेजी के लिए खेद है, यह मेरी मातृभाषा नहीं है।

+0

वाम जहां हालत भीतरी में शामिल होने के साथ शामिल हो। –

+0

आपको वास्तव में अपने टेबल डिज़ाइन पर पुनर्विचार करने की आवश्यकता है। स्टार्टर्स के लिए, एल्बम टेबल में स्ट्रिंग के रूप में कलाकार को संग्रहीत करना वास्तव में एक बुरा विचार है। यदि आप दोनों को "जॉन स्मिथ" कहा जाता है तो आप कलाकारों को अलग कैसे कहते हैं? आपके पास एल्बम टेबल में एक अलग कलाकार तालिका और स्टोर कलाकार आईडी होनी चाहिए। साथ ही, प्रत्येक शैली के लिए एक अलग टेबल रखना बुरा है। – GordonM

+0

@GordonM के बजाय एक शैली आईडी कॉलम रखें: यह सिर्फ एक उदाहरण था, मेरी तालिका ऐसा कुछ नहीं दिखती है लेकिन मैं बेहतर और आसान नहीं सोच सकता था। एल्बम टेबल में सभी कलाकारों और आईडी के साथ तालिका के साथ वैसे भी अच्छा विचार, धन्यवाद! – simivar

उत्तर

23

एक बाएं स्थिति में शामिल है और जहां स्थिति फ़िल्टर दोनों समान नहीं हैं। भौतिक सम्मिलन के बाद जहां खंड पर डेटा फ़िल्टर किया जाता है। यदि आप बाएं से जुड़ते हैं तो यह सामान्य रूप से आपकी बायीं तालिका से प्रत्येक पंक्ति को वापस कर देगा, लेकिन एक बार आपके पास एक क्लॉज होने के बाद, यह शामिल होने के आउटपुट को फ़िल्टर करेगा ताकि परिणाम आंतरिक जुड़ने जैसा हो। आप नीचे दी गई छवि के बाईं ओर दो आरेखों पर ध्यान केंद्रित करना चाहेंगे।

enter image description here

+0

बहुत सहज ज्ञान युक्त चित्र –

0

"वाम कीवर्ड रिटर्न सही तालिका (table2) में बाईं तालिका वाली सभी पंक्तियां (table1), मिलान पंक्तियों के साथ शामिल हों। परिणाम सही पक्ष में शून्य है जब है कोई मैच। "

उपर्युक्त उद्धरण w3schools.com

हालांकि, से है जब आप जहां एक वाम पर खंड में शामिल हों एक जगह, एसक्यूएल अब व्यवहार करता है एक अंदरूनी शामिल हों और के रूप में है कि:

"आंतरिक शामिल हों कीवर्ड से सभी पंक्तियों का चयन करता है दोनों टेबलों में कॉलम के बीच एक मैच है जब तक दोनों टेबल। "

इसके अलावा w3schools.com

TLDR से उद्धृत;

एक वाम बाहरी करने के लिए कहां खंड की शुरूआत में शामिल हों एक भीतर का व्यवहार में शामिल होने शामिल हों

+0

के लिए धन्यवाद मुझे विश्वास नहीं है कि बाएं प्रवेशकर्ता के रूप में ऐसी कोई चीज है। केवल अंदरूनी जॉइन हैं। कोई यहां इसके बारे में और अधिक पढ़ सकता है: http://stackoverflow.com/questions/2389204/left-inner-join-vs-left-outer-join-why-does-the-outer-take-longer –

2

पहले मामले देता है:

शामिल होने के बाद, रिकॉर्ड के आधार पर फ़िल्टर कर रहे हैं (कहां खंड)। तो केवल 1 परिणाम।

दूसरे मामले (जब आप और की जगह कहां के साथ)

वापसी करेंगे सभी दूसरी शर्त में संतुष्ट प्रविष्टियों + प्रविष्टियों में शामिल होने के (t2.rank! = 17)।यही कारण है कि यहां आपको 2 रिकॉर्ड प्राप्त होते हैं (एक दूसरे से और खंड में शामिल होने से)

+0

प्रत्येक शर्त के लिए जो बाएं जॉइन टेबल से मेल खाता है, बाएं से जुड़े कथन तक कहां स्थित है और AND का उपयोग करें – Baxny

0

SQL प्रश्न के निष्पादन आदेश या लॉजिकल क्वेरी प्रोसेसिंग चरणों के बारे में जागरूक होने पर इस प्रश्न का समाधान काफी सहज हो जाता है। आदेश है: -

1. FROM 
2. ON 
3. OUTER 
4. WHERE 
5. GROUP BY 
6. CUBE | ROLLUP 
7. HAVING 
8. SELECT 
9. DISTINCT 
10. ORDER BY 
11. TOP 

पर के रूप में के बाहरी (दायाँ/अधिकार) भाग (जोड़ने शून्य मूल्यवान पंक्तियों) से पहले किया जाता है शामिल हों, 1 मामले रैंक स्तम्भ में व्यर्थ मूल्यों के साथ पंक्तियां हैं। दूसरे मामले में बाहरी जॉइन (यहां बाएं जॉइन) के बाद रैंक कॉलम के मानों के आधार पर पंक्तियां फ़िल्टर की जाती हैं। इसलिए, रैंक कॉलम में नल मान वाले पंक्तियों को फ़िल्टर किया जाता है।

एक बहुत महत्वपूर्ण बात यह है कि अपने SQL क्वेरी में देखा जा सकता है जब शून्य/गैर-शून्य सामान्य अंकगणितीय ऑपरेटर का उपयोग कर मूल्यों के साथ शून्य परिणाम (यह NULL इस क्षेत्र के साथ तुलना शून्य मान के रूप में विशेष ध्यान देने की आवश्यकता है न तो सत्य और न ही गलत है) क्योंकि नल का मतलब तुलना के लिए कोई मूल्य उपलब्ध नहीं है। यह व्यवहार एएनएसआई एसक्यूएल-9 2 मानक में परिभाषित किया गया है। (ansi null (वास्तविक नाम भिन्न हो सकता है) कुछ एसक्यूएल प्रोसेसर में पैरामीटर बंद करके इसे ओवरराइड किया जा सकता है) तो, आपकी एसक्यूएल क्वेरी जहां क्लॉज एनयूएलएल के साथ पंक्तियों को फ़िल्टर करता है रैंक स्तंभ में मान जिससे उसे प्रति सहज ज्ञान युक्त करने के लिए "17! = शून्य" की वजह से लग सकता है लगता है सही ex-

शून्य = शून्य परिणाम शून्य/अज्ञात

17 = शून्य परिणाम शून्य/अज्ञात

17 ! = नल परिणाम नल? UNKNOWN

कुछ रोचक पोस्ट/संदर्भ के लिए ब्लॉग कर रहे हैं:

http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/ http://blog.sqlauthority.com/2009/03/15/sql-server-interesting-observation-of-on-clause-on-left-join-how-on-clause-effects-resultset-in-left-join/ http://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/

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