sql बनाम खंड पर अंदर शामिल हों




mysql join (8)

सादगी के लिए, मान लें कि सभी प्रासंगिक फ़ील्ड पूर्ण NOT NULL हैं।

तुम कर सकते हो:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

वरना:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

इन दो कामों को MySQL में उसी तरह से करें?


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

इसके अतिरिक्त रखरखाव के लिए यदि आपके पास पुराने वाक्यविन्यास में एक क्रॉस शामिल है, तो रखरखावकर्ता को कैसे पता चलेगा कि क्या आपके पास एक होना चाहिए (ऐसी परिस्थितियां हैं जहां क्रॉस जॉइन की आवश्यकता होती है) या यदि यह एक दुर्घटना थी जिसे ठीक किया जाना चाहिए?

यदि आप बाएं जुड़ने का उपयोग करते हैं तो यह देखने के लिए कि आप निहित वाक्यविन्यास खराब क्यों हैं, इस सवाल को आपको इंगित करने दें। Sybase * = एक ही आंतरिक तालिका के लिए 2 अलग बाहरी तालिकाओं के साथ Ansi मानक

इसके अलावा (यहां व्यक्तिगत रान), स्पष्ट जुड़ने का उपयोग करने वाला मानक 20 साल से अधिक पुराना है, जिसका अर्थ है कि उन 20 वर्षों के लिए अंतर्निहित वाक्यविन्यास पुराना हो गया है। क्या आप सिंटैक्स का उपयोग कर आवेदन कोड लिखेंगे जो 20 साल से पुराना हो गया है? आप डेटाबेस कोड क्यों लिखना चाहते हैं?


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

एक स्पष्ट जुड़ने का उपयोग (आपका दूसरा उदाहरण) बहुत अधिक पठनीय और बनाए रखने में आसान है।


चालू / कहां में सशर्त बयान लागू करना

यहां मैंने तार्किक क्वेरी प्रसंस्करण चरणों के बारे में समझाया है।

संदर्भ: माइक्रोसॉफ्ट® एसक्यूएल सर्वर ™ 2005 टी-एसक्यूएल क्वेरीिंग के अंदर
प्रकाशक: माइक्रोसॉफ्ट प्रेस
पब तिथि: 07 मार्च, 2006
प्रिंट करें आईएसबीएन -10: 0-7356-2313-9
प्रिंट करें आईएसबीएन -13: 978-0-7356-2313-2
पेज: 640

माइक्रोसॉफ्ट® एसक्यूएल सर्वर ™ 2005 टी-एसक्यूएल क्वेरीिंग के अंदर

(8)  SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>

एसक्यूएल का पहला ध्यान देने योग्य पहलू जो अन्य प्रोग्रामिंग भाषाओं से अलग है वह क्रम है जिसमें कोड संसाधित होता है। अधिकांश प्रोग्रामिंग भाषाओं में, कोड को उस क्रम में संसाधित किया जाता है जिसमें लिखा गया है। एसक्यूएल में, संसाधित किया गया पहला खंड खंड से है, जबकि चयन खंड, जो पहले दिखाई देता है, लगभग अंतिम संसाधित होता है।

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

लॉजिकल क्वेरी प्रोसेसिंग चरणों का संक्षिप्त विवरण

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

  1. से: एक कार्टेसियन उत्पाद (क्रॉस जॉइन) FROM खंड में पहले दो तालिकाओं के बीच किया जाता है, और नतीजतन, आभासी तालिका VT1 उत्पन्न होता है।

  2. चालू: चालू फ़िल्टर VT1 पर लागू होता है। केवल पंक्तियां जिसके लिए <join_condition> सत्य है VT2 में डाला गया है।

  3. बाहरी (शामिल): यदि एक बाहरी जॉइन निर्दिष्ट है (क्रॉस जॉइन या इनर जॉइन के विपरीत), संरक्षित टेबल या टेबल से पंक्तियां जिसके लिए एक मैच नहीं मिला था, बाहरी पंक्तियों के रूप में वीटी 2 से पंक्तियों में जोड़ा जाता है, उत्पन्न होता है VT3। यदि FROM खंड में दो से अधिक तालिकाएं दिखाई देती हैं, तो अंतिम तालिका के परिणाम और FROM खंड में अगली तालिका के परिणाम के बाद चरण 1 से 3 चरण बार-बार लागू होते हैं जब तक कि सभी तालिकाओं को संसाधित नहीं किया जाता है।

  4. कहां: जहां WHTE फ़िल्टर VT3 पर लागू होता है। केवल पंक्तियां जिसके लिए <where_condition> सत्य है <where_condition> में डाला गया है।

  5. ग्रुप बाय: ग्रुप बाय क्लॉज में उल्लिखित कॉलम सूची के आधार पर वीटी 4 की पंक्तियों को समूहों में व्यवस्थित किया जाता है। वीटी 5 उत्पन्न होता है।

  6. क्यूब | रोलअप: वीटी 5 उत्पन्न करने वाले सुपरग्रुप (समूहों के समूह) VT5 से पंक्तियों में जोड़े जाते हैं।

  7. हैविंग: हैविंग फ़िल्टर वीटी 6 पर लागू होता है। केवल वे समूह जिनके लिए <having_condition> सत्य है VT7 में डाला गया है।

  8. चुनें: चयन सूची संसाधित की जाती है, वीटी 8 उत्पन्न करती है।

  9. DISTINCT: VT8 से डुप्लिकेट पंक्तियां हटा दी जाती हैं। वीटी 9 उत्पन्न होता है।

  10. द्वारा आदेश: VT9 की पंक्तियों को ORDER BY खंड में निर्दिष्ट कॉलम सूची के अनुसार क्रमबद्ध किया जाता है। एक कर्सर उत्पन्न होता है (वीसी 10)।

  11. शीर्ष: पंक्तियों का निर्दिष्ट संख्या या प्रतिशत VC10 की शुरुआत से चुना जाता है। तालिका VT11 उत्पन्न होता है और कॉलर पर वापस आ जाता है।


इसलिए, (INNER JOIN) ON WHEE क्लॉज लागू करने से पहले डेटा फ़िल्टर करेगा (VT की डेटा गणना यहां कम हो जाएगी)। बाद में शामिल स्थितियों को फ़िल्टर किए गए डेटा के साथ निष्पादित किया जाएगा जो प्रदर्शन में सुधार करता है। उसके बाद केवल WHERE स्थिति फ़िल्टर स्थितियों को लागू करेगी।

(चालू / कहां में सशर्त बयान लागू करने से कुछ मामलों में बहुत अंतर नहीं आएगा। यह इस बात पर निर्भर करता है कि आप कितनी तालिकाओं में शामिल हुए हैं और प्रत्येक जॉइन टेबल में पंक्तियों की संख्या उपलब्ध है)


उनके पास एक अलग मानव-पठनीय अर्थ है।

हालांकि, क्वेरी ऑप्टिमाइज़र के आधार पर, उनके पास मशीन के समान अर्थ हो सकता है।

आपको हमेशा पठनीय होने के लिए कोड होना चाहिए।

यही कहना है, यदि यह एक अंतर्निहित संबंध है, तो स्पष्ट शामिल होने का उपयोग करें। यदि आप कमजोर संबंधित डेटा से मेल खाते हैं, तो खंड कहां उपयोग करें।


एसक्यूएल: 2003 मानक ने कुछ प्राथमिकता नियमों को बदल दिया है, इसलिए एक जॉइन स्टेटमेंट को "अल्पविराम" में शामिल होने पर प्राथमिकता दी जाती है। यह वास्तव में आपकी क्वेरी के परिणामों को कैसे बदल सकता है इस पर निर्भर करता है। इससे कुछ लोगों के लिए कुछ समस्याएं होती हैं जब MySQL 5.0.12 मानक का पालन करने के लिए स्विच किया जाता है।

तो आपके उदाहरण में, आपके प्रश्न समान काम करेंगे। लेकिन अगर आपने तीसरी तालिका जोड़ दी है: चुनें ... तालिका 1 से, table2 टेबल 3 में शामिल हों ... कहां ...

MySQL 5.0.12 से पहले, तालिका 1 और तालिका 2 पहले शामिल हो जाएगा, फिर तालिका 3। अब (5.0.12 और चालू), तालिका 2 और तालिका 3 पहले शामिल हो गए हैं, फिर तालिका 1। यह हमेशा परिणामों को नहीं बदलता है, लेकिन यह कर सकता है और आप इसे भी महसूस नहीं कर सकते हैं।

मैं आपके दूसरे उदाहरण का चयन करने के लिए अब "अल्पविराम" वाक्यविन्यास का कभी भी उपयोग नहीं करता हूं। वैसे भी यह बहुत अधिक पठनीय है, जॉइन की स्थिति जॉइन के साथ हैं, एक अलग क्वेरी खंड में अलग नहीं है।


एएनएसआई सिंटैक्स में शामिल है निश्चित रूप से अधिक पोर्टेबल है।

मैं माइक्रोसॉफ्ट एसक्यूएल सर्वर के अपग्रेड के माध्यम से जा रहा हूं, और मैं यह भी उल्लेख करता हूं कि SQL सर्वर में बाहरी जुड़ने के लिए = * और * = वाक्यविन्यास 2005 एसक्यूएल सर्वर और बाद में समर्थित नहीं है (संगतता मोड के बिना)।


मुझे पता है कि आप MySQL के बारे में बात कर रहे हैं, लेकिन वैसे भी: ओरेकल 9 में स्पष्ट रूप से शामिल हो जाते हैं और निहित जुड़ने से विभिन्न निष्पादन योजनाएं उत्पन्न होती हैं। AFAIK जिसे ओरेकल 10+ में हल किया गया है: अब ऐसा कोई अंतर नहीं है।


INNER JOIN एएनएसआई सिंटैक्स है जिसका आपको उपयोग करना चाहिए।

इसे आम तौर पर अधिक पठनीय माना जाता है, खासकर जब आप बहुत सारी टेबल में शामिल होते हैं।

जब भी आवश्यकता होती है तो इसे आसानी से एक OUTER JOIN साथ भी बदला जा सकता है।

WHERE वाक्यविन्यास अधिक रिलेशनल मॉडल उन्मुख है।

दो तालिकाओं का परिणाम JOIN एड टेबल का एक कार्टेशियन उत्पाद है जिसमें फ़िल्टर लागू होता है जो कॉलम मिलान में शामिल होने के साथ ही उन पंक्तियों का चयन करता है।

WHERE वाक्यविन्यास के साथ इसे देखना आसान है।

आपके उदाहरण के लिए, MySQL (और आमतौर पर एसक्यूएल में) इन दो प्रश्न समानार्थी हैं।

यह भी ध्यान रखें कि MySQL में STRAIGHT_JOIN क्लॉज भी है।

इस खंड का उपयोग करके, आप JOIN ऑर्डर को नियंत्रित कर सकते हैं: बाहरी लूप में कौन सी तालिका स्कैन की गई है और कौन सा आंतरिक लूप में है।

आप WHERE वाक्यविन्यास का उपयोग कर MySQL में इसे नियंत्रित नहीं कर सकते हैं।





inner-join