2011-01-20 17 views
103

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

लेकिन यह क्वेरी केवल उन सेटिंग्स को पुनर्प्राप्त कर रही है जहां वर्ण = 1 है, यदि उपयोगकर्ता ने किसी को भी सेट किया है तो डिफ़ॉल्ट सेटिंग्स नहीं।

SELECT `settings`.*, `character_settings`.`value` 
FROM (`settings`) 
LEFT JOIN `character_settings` 
ON `character_settings`.`setting_id` = `settings`.`id` 
WHERE `character_settings`.`character_id` = '1' 

तो मैं कुछ इस तरह की जरूरत है चाहिए:

array(
    '0' => array('somekey' => 'keyname', 'value' => 'thevalue'), 
    '1' => array('somekey2' => 'keyname2'), 
    '2' => array('somekey3' => 'keyname3') 
) 

कहाँ कुंजी 1 और 2 मूलभूत मूल्यों हैं जब कुंजी 0 चरित्र मूल्य के साथ डिफ़ॉल्ट मान है।

उत्तर

240

where खंड पंक्तियों को फ़िल्टर कर रहा है जहां left join सफल नहीं होता है। यह करने के लिए ले जाएँ शामिल हो:

SELECT `settings`.*, `character_settings`.`value` 
FROM `settings` 
LEFT JOIN 
     `character_settings` 
ON  `character_settings`.`setting_id` = `settings`.`id` 
     AND `character_settings`.`character_id` = '1' 
12

अगर मैं अपने प्रश्न समझ में सही ढंग से आप सेटिंग्स डेटाबेस से रिकॉर्ड चाहते हैं, तो वे एक character_settings मेज पर करवाते में शामिल होने या यदि वह शामिल हो गए रिकॉर्ड = 1.

character_id है की जरूरत नहीं है

इसलिए करना चाहिए

SELECT `settings`.*, `character_settings`.`value` 
FROM (`settings`) 
LEFT OUTER JOIN `character_settings` 
ON `character_settings`.`setting_id` = `settings`.`id` 
WHERE `character_settings`.`character_id` = '1' OR 
`character_settings`.character_id is NULL 
+4

झूठी सकारात्मक –

+0

@OMGPonies को वापस करने का जोखिम मुझे समझ में नहीं आता है, इसके जोखिम क्या हो सकते हैं। मेरे मामले में मैंने शामिल किया और शामिल होने के साथ आवेदन किया और कोई परिणाम नहीं था, लेकिन जब मैंने समाधान के ऊपर उपयोग किया, तो मेरे पास परिणाम थे। लेकिन मैं इस विकल्प के साथ सामना करने वाले मुद्दों के बारे में निश्चित होना चाहता हूं। –

+0

धन्यवाद। अच्छा उत्तर। –

41

जब जिससे बाहरी मिलती है (एएनएसआई-89 या एएनएसआई-92), निस्पंदन स्थान मामलों क्योंकि ON खंड में निर्दिष्ट मापदंड शामिल हों 01 किया जाता है से पहले लागू किया जाता है । WHERE क्लॉज में प्रदान की गई एक बाहरी जॉइन टेबल के खिलाफ मानदंड बनने के बाद लागू किया गया है। यह बहुत अलग परिणाम सेट का उत्पादन कर सकते हैं। तुलनात्मक रूप से, यह INNER जॉइन के लिए कोई फर्क नहीं पड़ता अगर मानदंड ON या WHERE खंडों में प्रदान किया जाता है - परिणाम वही होगा।

SELECT s.*, 
      cs.`value` 
    FROM SETTINGS s 
LEFT JOIN CHARACTER_SETTINGS cs ON cs.setting_id = s.id 
           AND cs.character_id = 1 
1

आप यह आसान, एक सरल सबक्वेरी

SELECT `settings`.*, (
    SELECT `value` FROM `character_settings` 
    WHERE `character_settings`.`setting_id` = `settings`.`id` 
     AND `character_settings`.`character_id` = '1') AS cv_value 
FROM `settings` 

सबक्वेरी अशक्त वापस जाने के लिए अनुमति दी है का उपयोग करके समझने के लिए तो आप मुख्य क्वेरी में चिंता करने की कहां शामिल हों/के बारे में नहीं है मिल सकती है ।

कभी-कभी, यह तेजी से MySQL में काम करता है, लेकिन यह देखने के लिए बाएं जॉइन फॉर्म के विरुद्ध इसकी तुलना करें कि यह आपके लिए सबसे अच्छा काम करता है।

SELECT s.*, c.value 
FROM settings s 
LEFT JOIN character_settings c ON c.setting_id = s.id AND c.character_id = '1' 
0

परिणाम SQL कथन के आधार पर सही है। बाएं जुड़ें दाएं तालिका से सभी मान लौटाते हैं, और बाएं तालिका से केवल मिलान मान।

आईडी और NAME कॉलम दाईं ओर तालिका से हैं, इसलिए लौटाए जाते हैं।

स्कोर बाएं तालिका से है, और 30 वापस आ गया है, क्योंकि यह मान नाम "फ़्लो" से संबंधित है। अन्य नाम नल हैं क्योंकि वे नाम "फ्लो" से संबंधित नहीं हैं।

नीचे परिणाम आप उम्मीद कर रहे थे वापसी होगी:

SELECT a.*, b.Score 
FROM @Table1 a 
    LEFT JOIN @Table2 b 
     ON a.ID = b.T1_ID 
WHERE 1=1 
AND a.Name = 'Flow' 

एसक्यूएल दाहिने हाथ मेज पर एक फिल्टर लागू होता है।