इनर बनाम जो क्लॉज में शामिल हों


941

सादगी के लिए, मान लें कि सभी प्रासंगिक क्षेत्र हैं 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?




18
अगर मैं सही तरीके से समझ गया हूं, तो पहला वेरिएंट ANSI SQL-89 निहित सिंटैक्स है और दूसरा वेरिएंट ANSI SQL-92 स्पष्ट सिंटैक्स में शामिल है। दोनों ही SQL क्रियान्वयन के अनुरूप होने के परिणामस्वरूप समान परिणाम होंगे और दोनों ही अच्छी तरह से किए गए SQL कार्यान्वयन में समान क्वेरी योजना के परिणामस्वरूप होंगे। मैं व्यक्तिगत रूप से SQL-89 सिंटैक्स पसंद करता हूं, लेकिन बहुत से लोग SQL-92 सिंटैक्स पसंद करते हैं।
मिक्को रेंटालीनें

11
@ होगन मैं विभिन्न सिंटैक्स के लिए आधिकारिक नामों की ओर इशारा कर रहा था। उत्तर में से किसी ने भी स्पष्ट रूप से पूर्ण नामों को नहीं लिखा है, इसलिए मैंने उन टिप्पणियों के रूप में जोड़ने का फैसला किया। हालाँकि, मेरी टिप्पणी ने वास्तविक प्रश्न का उत्तर नहीं दिया, इसलिए मैंने टिप्पणी के रूप में जोड़ा, उत्तर के रूप में नहीं। (उच्च मत वाले उत्तर में दावा है कि "INNER JOIN ANSI सिंटैक्स है" और "ANSI सिंटैक्स पुराना है, इसका निहितार्थ" है, जो कुछ भी नहीं कहता है क्योंकि दोनों सिंटैक्स अलग-अलग ANSI सिंटैक्स हैं।)
मिको रैनतैसेन

जवाबों:


710

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

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

OUTER JOINजब भी जरूरत पड़ती है, इसे आसानी से बदला जा सकता है।

WHEREवाक्य रचना अधिक संबंधपरक मॉडल उन्मुख है।

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

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

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

यह भी ध्यान दें कि MySQL का एक STRAIGHT_JOINक्लॉज भी है ।

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

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


10
धन्यवाद, क्वासोई। आपके पास आपके विवरण में बहुत कुछ है; क्या यह कहना उचित है कि "हाँ, वे प्रश्न समतुल्य हैं, लेकिन आपको आंतरिक जुड़ाव का उपयोग करना चाहिए क्योंकि यह अधिक पठनीय है, और संशोधित करना आसान है"?
अलॉयरोड जूल

8
@allyourcode: के लिए Oracle, SQL Server, MySQLऔर PostgreSQL- हाँ। अन्य प्रणालियों के लिए, शायद, भी, लेकिन आप बेहतर जांच करते हैं।
क्वासोइ

13
एफडब्ल्यूआईडब्ल्यू, WHEREक्लॉज में शामिल होने की स्थितियों के साथ अल्पविराम का उपयोग करना एएनएसआई मानक में भी है।
बिल करविन

1
@Bill Karwin: JOINकीवर्ड पिछले कुछ समय तक मालिकाना मानकों का हिस्सा नहीं था, जो कि हाल ही में प्रतीत हो सकता है। इसने Oracleकेवल संस्करण में 9और PostgreSQLसंस्करण में 7.2(दोनों में जारी 2001) में अपना रास्ता बनाया । इस कीवर्ड की उपस्थिति ANSIमानक अपनाने का एक हिस्सा थी , और यही कारण है कि यह कीवर्ड आमतौर पर साथ जुड़ा हुआ है ANSI, इस तथ्य के बावजूद कि बाद वाला कॉमा के समानार्थी के CROSS JOINरूप में कॉमा का समर्थन करता है ।
क्वासोई

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

182

अन्य लोगों ने बताया कि INNER JOINमानव पठनीयता में मदद करता है, और यह एक सर्वोच्च प्राथमिकता है, मैं सहमत हूं।
मुझे यह समझाने की कोशिश करें कि सम्मिलित वाक्यविन्यास अधिक पठनीय क्यों है।

एक बुनियादी SELECTप्रश्न यह है:

SELECT stuff
FROM tables
WHERE conditions

SELECTखंड हमें बताता है क्या हम वापस हो रही है; FROMखंड हमें बताता है जहां हम से यह हो रही है, और WHEREखंड हमें बताता है जो लोगों को हम हो रही है।

JOIN तालिकाओं के बारे में एक कथन है, वे कैसे एक साथ बंधे हैं (वैचारिक रूप से, वास्तव में, एक ही तालिका में)।

किसी भी क्वेरी तत्व जो तालिकाओं को नियंत्रित करते हैं - जहां हम सामान प्राप्त कर रहे हैं - शब्दार्थ FROMखंड (और निश्चित रूप से, यही वह JOINतत्व है जहां तत्व जाते हैं)। ज्वाइनिंग-एलीमेंट्स को WHEREक्लॉज में डालने से कौन सा और कहां-कहां से अलग होता है , इसीलिए JOINसिंटैक्स पसंद किया जाता है।


7
यह स्पष्ट करने के लिए धन्यवाद कि आंतरिक जुड़ाव कार्ल को क्यों पसंद है। मुझे लगता है कि आपका ans दूसरों में निहित था, लेकिन स्पष्ट रूप से आमतौर पर बेहतर होता है (हाँ, मैं एक पायथन प्रशंसक हूं)।
अल्लौरकोड

2
ऑन एंड व्हेयर के शब्दार्थ का अर्थ है कि अंतिम ओआरओएस जॉइन के बाद जॉइन के लिए यह कोई फर्क नहीं पड़ता कि आप किसका उपयोग करते हैं। यद्यपि आप ONIN JOIN के भाग के रूप में विशेषता रखते हैं, यह कार्टेशियन उत्पाद के बाद फ़िल्टरिंग भी है। ON और WHERE दोनों एक कार्टेशियन उत्पाद को फ़िल्टर करते हैं। लेकिन जहां पर या तो सबस्क्रिप्शन के साथ अंतिम OUTER JOIN से पहले इस्तेमाल किया जाना चाहिए । (कॉलम जोड़े पर "JOINs" नहीं हैं। किसी भी हालत में किसी भी दो तालिकाओं को जोड़ा जा सकता है। यह कॉलम की समानता पर विशेष रूप से JOINs की व्याख्या करने का एक तरीका है।)
फिलिपींस

जब आप INNER JOIN के समान प्रभाव का उपयोग कर रहे हैं, तब भी आप क्वेरी के FROM भाग में अपनी दो तालिकाओं का उल्लेख करने जा रहे हैं। इसलिए मूल रूप से आप अभी भी जहाँ आप अपना डेटा FROM क्लॉज़ में प्राप्त कर रहे हैं, तो मुझे लगता है कि आप यह नहीं कह सकते हैं कि यह आवश्यक रूप से "कौन और कहाँ से है"
cybergeek654

@ArsenKhachaturyan सिर्फ इसलिए कि पाठ में एक कीवर्ड या पहचानकर्ता का उपयोग किया जाता है इसका मतलब यह नहीं है कि यह कोड है और कोड प्रारूप की आवश्यकता है। यह एक प्रारूपण विकल्प है जो किसी भी तरह से जा सकता है और अगर यहां संपादित करना उचित है तो हर पोस्ट को दूसरे प्रारूप में लगातार संपादित करना उचित है - जो यह कहना है, यह उचित नहीं है। (प्लस इनलाइन प्रति शब्द कोड प्रारूप को पढ़ना मुश्किल हो सकता है।) यहाँ पैराग्राफ को तोड़ने के लिए समान - वे विशेष रूप से स्पष्ट नहीं हैं। उसी के साथ 'जो' बनाम 'वह'। और प्रोग्रामिंग भाषाओं के नाम कोड प्रारूप में नहीं होने चाहिए । PS आपने गलती से लाइन ब्रेक जोड़ दिया।
फिलीपिक्सी

@philipxy जैसा कि आपने "इसका मतलब यह नहीं है ..." का उल्लेख किया है, लेकिन जाहिर है इसका मतलब यह नहीं है कि इसे कोड कीवर्ड के साथ चिह्नित नहीं किया जा सकता है। हाँ, यह पसंद किया जा सकता है लेकिन बहुत सारे पोस्ट उस तथ्य को जाने बिना किए जाते हैं। इसलिए बदलाव करने के मेरे निर्णय का उद्देश्य कुछ भी तोड़ना नहीं है बल्कि इसे और अधिक पठनीय बनाना है। यदि आपने परिवर्तनों को बनाने के बाद किसी भी तरह का ध्यान दिया है, तो उसके लिए क्षमा करें, और आप स्पष्ट रूप से ऐसे परिवर्तनों को वापस ला सकते हैं।
आर्सेन खाचरौतन

143

ON / WHERE में सशर्त विवरण लागू करना

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


संदर्भ: अंदर Microsoft® SQL Server ™ 2005 T-SQL क्वेरी
प्रकाशक: Microsoft प्रेस
पब दिनांक: मार्च ०,, २००६
प्रिंट आईएसबीएन -१०: ० -३३५६-२३१३-
९ प्रिंट आईएसबीएन -१३: ९- 0--०-35३५६-२३१३-२
पेज: 640

Microsoft® SQL Server ™ 2005 T-SQL क्वेरी के अंदर

(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>

SQL का पहला ध्यान देने योग्य पहलू जो अन्य प्रोग्रामिंग भाषाओं की तुलना में अलग है, वह क्रम है जिसमें कोड संसाधित होता है। अधिकांश प्रोग्रामिंग भाषाओं में, कोड उस क्रम में संसाधित होता है जिसमें यह लिखा जाता है। SQL में, संसाधित किया गया पहला खंड FROM खंड है, जबकि SELECT खंड, जो पहले प्रकट होता है, लगभग अंतिम रूप से संसाधित होता है।

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

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

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

  1. FROM: FROM क्लॉज में पहले दो तालिकाओं के बीच एक कार्टेशियन उत्पाद (क्रॉस जॉइन) किया जाता है, और परिणामस्वरूप वर्चुअल टेबल VT1 उत्पन्न होता है।

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

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

  4. जहां: वीटी 3 पर फिल्टर लगाया जाता है। केवल वे पंक्तियाँ जिनके लिए <where_condition>TRUE है, VT4 में सम्मिलित हैं।

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

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

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

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

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

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

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



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

(ON / WHERE में सशर्त विवरण लागू करने से कुछ मामलों में बहुत अधिक फर्क नहीं पड़ेगा। यह निर्भर करता है कि आप कितने टेबल में शामिल हुए हैं और प्रत्येक ज्वाइन टेबल में उपलब्ध पंक्तियों की संख्या)


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

@rafidheen "(INNER JOIN) ON डेटा को फ़िल्टर करेगा ... WHERE क्लॉज़ लगाने से पहले ... जो प्रदर्शन को बेहतर बनाता है।" अच्छी बात। "उसके बाद केवल WHERE की स्थिति फ़िल्टर शर्तों को लागू करेगी" HAVING खंड के बारे में क्या?
जेम्स

@ जफेदीन का दावा गलत है। मैनुअल में 'ज्वाइन ऑप्टिमाइजेशन' देखें। इस पृष्ठ पर मेरी अन्य टिप्पणियाँ भी। (और माइकशेरिल'कैटरेक्लास।) इस तरह के "तार्किक" विवरण परिणाम मूल्य का वर्णन करते हैं, न कि यह कि वास्तव में इसकी गणना कैसे की जाती है। और इस तरह के कार्यान्वयन व्यवहार को नहीं बदलने की गारंटी नहीं है।
फिलिप्पि

66

निहित एएनएसआई सिंटैक्स पुराना है, कम स्पष्ट है और अनुशंसित नहीं है।

इसके अलावा, संबंधपरक बीजगणित, WHEREखंड और में विधेय के विनिमेयता की अनुमति देता है INNER JOIN, इसलिए खंड के INNER JOINसाथ प्रश्न भी WHEREआशावादी द्वारा पुन: व्यवस्थित किए जा सकते हैं।

मैं आपको सबसे अधिक संभव तरीके से प्रश्नों को लिखने की सलाह देता हूं।

कभी-कभी इसमें INNER JOINअपेक्षाकृत "अधूरा" बनाना और कुछ मानदंड को WHEREआसानी से फ़िल्टर करने की सूची को और अधिक आसानी से बनाए रखा जा सकता है।

उदाहरण के लिए, इसके बजाय:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

लिखो:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

लेकिन यह निर्भर करता है, निश्चित रूप से।


16
आपका पहला स्निपेट निश्चित रूप से मेरे मस्तिष्क को अधिक चोट पहुँचाता है। क्या वास्तव में कोई ऐसा करता है? अगर मैं किसी से मिलता हूं जो ऐसा करता है, क्या मेरे लिए उसे सिर पर पीटना ठीक है?
अल्लौरकोड

3
मैं उन मानदंडों का पता लगाता हूं जहां यह सबसे अधिक समझ में आता है। यदि मैं एक अस्थायी रूप से सुसंगत स्नैपशॉट लुकअप तालिका में शामिल हो रहा हूं (और मेरे पास कोई दृश्य या UDF नहीं है जो एक वैध तिथि के चयन को लागू करता है), तो मैं प्रभावी तिथि को शामिल करूँगा और न कि WHERE में शामिल करूंगा क्योंकि यह कम है गलती से निकालने की संभावना है।
केड रूक्स जूल 26'09

14
@allyourcode: हालाँकि INNER JOINs में इस प्रकार के ज्वाइन सिंटैक्स को देखना दुर्लभ है, यह RIGHT JOINs और LEFT JOINS के लिए काफी सामान्य है - Join predicate में अधिक विवरण निर्दिष्ट करना एक सब-वेरी की आवश्यकता को समाप्त करता है और आपके बाहरी जोड़ों को अनजाने में बदलने से रोकता है। ININ JOINs में। (हालांकि मैं मानता हूं कि INNER JOINs के लिए मैं लगभग हमेशा c.State = 'NY' को WHERE क्लॉज में डालूंगा)
डेव मार्कल

1
@allyourcode मैं निश्चित रूप से ऐसा करता हूँ! और मैं केड के साथ सहमत हूं .. मैं उत्सुक हूं कि क्या एक सभ्य कारण नहीं है
आर्थर

31

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

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


48
मैं इससे ज्यादा असहमत नहीं हो सकता। जॉय सिंटैक्स बेहद चिंताजनक और व्यवस्थित करने में मुश्किल है। मेरे पास 5, 10, 15 तालिकाओं में से भी बहुत सी क्वेरीज़ हैं, जिनमें से क्लॉज़ जॉइन का उपयोग करते हुए वे पूरी तरह से पठनीय हैं। JOIN सिंटैक्स का उपयोग करके ऐसी क्वेरी को पुन: प्राप्त करने से गड़बड़ी गड़बड़ हो जाती है। जो सिर्फ यह दिखाने के लिए जाता है कि इस सवाल का कोई सही जवाब नहीं है और यह इस बात पर अधिक निर्भर करता है कि आप किस चीज के साथ सहज हैं।
नूह यश

33
नूह, मुझे लगता है कि आप यहाँ अल्पसंख्यक हो सकते हैं।
मैट बी

2
मुझे मैट और नूह को +1 मिलता है। मुझे विविधता पसंद है :)। मैं देख सकता हूं कि नूह कहां से आ रहा है; आंतरिक जुड़ाव भाषा में कुछ नया नहीं जोड़ता है, और निश्चित रूप से अधिक क्रिया है। दूसरी ओर, यह आपकी 'जहां' स्थिति को बहुत कम कर सकता है, जिसका अर्थ है आमतौर पर इसे पढ़ना आसान होता है।
एलियोरकोड

5
मुझे लगता है कि किसी भी समझदार DBMS दो प्रश्नों को एक ही निष्पादन योजना में अनुवाद करेगा; हालांकि वास्तव में प्रत्येक डीबीएमएस अलग है और यह सुनिश्चित करने का एकमात्र तरीका वास्तव में निष्पादन योजना की जांच करना है (यानी, आपको स्वयं परीक्षण करना होगा)।
मैट बी

क्या यह सच है जैसा कि @rafidheen ने एक अन्य उत्तर (SQL निष्पादन के विस्तृत अनुक्रम के साथ) में सुझाव दिया है कि JOIN को एक बार में फ़िल्टर्ड किया जाता है, जब पूर्ण कार्टेशियन 3 या अधिक तालिकाओं के पूर्णांक की तुलना में जुड़ने के आकार को कम किया जाता है। कहाँ फ़िल्टर किया जा रहा है रेट्रोएक्टली? यदि ऐसा है, तो यह सुझाव देगा कि JOIN प्रदर्शन सुधार प्रदान करता है (साथ ही साथ बाएं / दाएं जोड़ों में लाभ, जैसा कि एक अन्य उत्तर पर भी बताया गया है)।
जेम्स

26

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

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

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

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


3
@HLGEM: जबकि मैं पूरी तरह सहमत हूं कि स्पष्ट JOIN बेहतर हैं, ऐसे मामले हैं जब आपको बस पुराने सिंटैक्स का उपयोग करने की आवश्यकता होती है। एक वास्तविक दुनिया उदाहरण: ANSI JOIN केवल 9i संस्करण में Oracle में मिला, जो 2001 में जारी किया गया था, और केवल एक साल पहले तक (जब मानक प्रकाशित किया गया था तब से 16 साल) मुझे 8i स्थापना का एक गुच्छा समर्थन करना था जिसके लिए हमारे पास था महत्वपूर्ण अपडेट जारी करने के लिए। मैं अद्यतनों के दो सेटों को बनाए रखना नहीं चाहता था, इसलिए हमने 8i सहित सभी डेटाबेसों के खिलाफ अद्यतनों का विकास और परीक्षण किया, जिसका मतलब था कि हम एएनएसआई जॉइन का उपयोग करने में असमर्थ थे।
क्वासोई

+1 दिलचस्प बिंदु जब आप इंगित करते हैं कि INNER JOIN के बिना सिंटैक्स अधिक त्रुटि वाला है। जब आप कहते हैं कि मैं आपके अंतिम वाक्य के बारे में उलझन में हूं "... स्पष्ट अक्षरों का उपयोग करने वाला मानक 17 साल पुराना है।" तो क्या आप तब INNER JOIN कीवर्ड का उपयोग करने का सुझाव दे रहे हैं या नहीं?
मार्को डेमायो

1
@ मार्को डेमायो, हाँ हमेशा INNER JOIN या JOIN (ये दोनों एक ही हैं) या LEFT JOIN या RIGHT JOIN या CROSS JOIN का उपयोग करें और कभी भी अंतर्निहित कॉमा जॉइन का उपयोग न करें।
HLGEM

2
"आप डेटाबेस कोड क्यों लिखना चाहते हैं जो [20 साल पुराना] है?" - जब से SQL ने व्युत्पन्न तालिकाओं का समर्थन करना शुरू किया है, मुझे लगता है कि आपने SQL का उपयोग करते हुए HAVING'पुराना' लिख दिया है। मैं यह भी ध्यान देता हूं कि आप इसका उपयोग नहीं NATURAL JOINकरेंगे, हालांकि मैं तर्क देता हूं कि इसने INNER JOIN'पुराना' बना दिया है । हां, आपके पास आपके कारण हैं (उन्हें यहां फिर से बताने की आवश्यकता नहीं है!): मेरा कहना है, जो लोग पुराने सिंटैक्स का उपयोग करना पसंद करते हैं, उनके कारण भी हैं और सिंटैक्स की सापेक्ष उम्र कम है अगर कोई प्रासंगिकता है।
onedaywhen

1
जहां अभी भी मानक में है (मुझे दिखाओ कि वह कहां नहीं है)। इसलिए, कुछ भी पुराना नहीं है, जाहिरा तौर पर। इसके अलावा, मुझे पता चलता है एक डेवलपर हैं जो सामान्य रूप में DBMSs से दूर रखा जाना चाहिए, "बल्कि फिक्सिंग से शामिल होने के" दूर दूर।
जुरगेन ए। इरहाद

12

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

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

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

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


11

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

इसलिए आपके उदाहरण में, आपके प्रश्न समान होंगे। लेकिन अगर आपने एक तीसरी तालिका जोड़ी: चयन करें ... तालिका 1 से, तालिका 2 को शामिल करें।

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

मैं कभी भी "अल्पविराम" वाक्य-विन्यास का उपयोग नहीं करता, आपके दूसरे उदाहरण के लिए। यह वैसे भी बहुत अधिक पठनीय है, JOIN परिस्थितियाँ JOINs के साथ हैं, एक अलग क्वेरी सेक्शन में नहीं।


मानक SQL नहीं बदला। MySQL सिर्फ गलत था और अब सही है। MySQL मैनुअल देखें।
फिलीपिक्सी

4

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


1

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

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


2
SQL Server 2000 में भी, = और = गलत परिणाम दे सकता है और इसका उपयोग कभी नहीं किया जाना चाहिए।
एचएलजीईएम

2
*=और =*एएनएसआई कभी नहीं थे और कभी भी एक अच्छी धारणा नहीं थे। इसलिए ON की जरूरत थी - सब-इलेक्ट्स की अनुपस्थिति में OUTER JOINs के लिए (जो एक ही समय में जुड़ गया, इसलिए उन्हें वास्तव में CROSS & INNER JOINs में जरूरत नहीं है।)
22:26 पर

1

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.