ऑन क्लॉज की स्थिति का वास्तव में क्या मतलब है?


23

सामान्य JOIN ... ON ...वाक्य-विन्यास सर्वविदित है। लेकिन यह भी संभव है कि यह ONजिस से JOINमेल खाती है, उससे क्लॉज को अलग से रखें । यह कुछ ऐसा है जो शायद ही कभी अभ्यास में देखा जाता है, ट्यूटोरियल में नहीं पाया जाता है और मुझे ऐसा कोई भी वेब संसाधन नहीं मिला है जिसमें उल्लेख किया गया हो कि यह संभव है।

यहाँ एक स्क्रिप्ट के साथ खेलने के लिए है:

SELECT *
INTO #widgets1
FROM (VALUES (1), (2), (3)) x(WidgetID)


SELECT *
INTO #widgets2
FROM (VALUES (1, 'SomeValue1'), (2, 'SomeValue2'), (3, 'SomeValue3')) x(WidgetID, SomeValue)

SELECT *
INTO #widgetProperties
FROM (VALUES
    (1, 'a'), (1, 'b'),
    (2, 'a'), (2, 'b'))
x(WidgetID, PropertyName)


--q1
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN #widgets2 w2 ON w2.WidgetID = w1.WidgetID
LEFT JOIN #widgetProperties wp ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b'
ORDER BY w1.WidgetID


--q2
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN #widgets2 w2 --no ON clause here
JOIN #widgetProperties wp
 ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b'
 ON w2.WidgetID = w1.WidgetID
ORDER BY w1.WidgetID


--q3
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN (
    #widgets2 w2 --no SELECT or FROM here
    JOIN #widgetProperties wp
    ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b')
ON w2.WidgetID = w1.WidgetID
ORDER BY w1.WidgetID

q1 सामान्य लग रहा है। q2 और q3 में ONक्लॉज़ की ये असामान्य स्थितियाँ हैं ।

जरूरी नहीं कि यह स्क्रिप्ट बहुत मायने रखती है। मेरे लिए एक सार्थक परिदृश्य को तैयार करना कठिन था।

तो इन असामान्य सिंटैक्स पैटर्न का क्या मतलब है? यह कैसे परिभाषित किया गया है? मैंने देखा कि दो ONखंडों के लिए सभी पदों और आदेशों की अनुमति नहीं है। इसे नियंत्रित करने वाले नियम क्या हैं?

इसके अलावा क्या कभी इस तरह के प्रश्न लिखना एक अच्छा विचार है?

जवाबों:


32

यदि आप FROMक्लॉज सिंटैक्स आरेख को देखते हैं, तो आप देखेंगे कि ONक्लॉज के लिए केवल एक ही स्थान है :

<joined_table> ::= 
{
    <table_source> <join_type> <table_source> ON <search_condition> 
    ...
}

क्या आपको संशय, सरल प्रत्यावर्तन है, क्योंकि <table_source>में <joined_table> ऊपर एक और हो सकता है <joined_table>:

[ FROM { <table_source> } [ ,...n ] ] 
<table_source> ::= 
{
    table_or_view_name ... 
    ...
    | <joined_table> 
    ...
}

भ्रम से बचने के लिए आपको गैर-स्पष्ट मामलों (जैसे आपके उदाहरण) में कोष्ठक का उपयोग नेत्रहीन अलग करना चाहिए <table_sources>; वे क्वेरी पार्सर के लिए आवश्यक नहीं हैं, लेकिन मनुष्यों के लिए उपयोगी हैं।


33

यह जुड़ने में शामिल तार्किक तालिकाओं को निर्धारित करता है।

एक साधारण उदाहरण के साथ

SELECT w1.WidgetID,
       w2.SomeValue,
       wp.PropertyName
FROM   #widgets1 w1
       LEFT JOIN #widgets2 w2
         ON w2.WidgetID = w1.WidgetID
       JOIN #widgetProperties wp
         ON w2.WidgetID = wp.WidgetID
            AND wp.PropertyName = 'b'
ORDER  BY w1.WidgetID 

#widgets1बाहरी रूप से जुड़ गया है #widgets2- इसके परिणामस्वरूप एक आभासी तालिका बनती है जो आंतरिक रूप से जुड़ जाती है #widgetProperties। विधेय w2.WidgetID = wp.WidgetIDका अर्थ यह होगा कि आरंभिक बाहरी जोड़ से किसी भी अशक्त विस्तारित पंक्तियों को फ़िल्टर किया जाता है, जिससे प्रभावी रूप से सभी जोड़ आंतरिक जुड़ जाते हैं।

यह q2 से अलग है ...

SELECT w1.WidgetID,
       w2.SomeValue,
       wp.PropertyName
FROM   #widgets1 w1
       LEFT JOIN #widgets2 w2 --no ON clause here
                 JOIN #widgetProperties wp
                   ON w2.WidgetID = wp.WidgetID
                      AND wp.PropertyName = 'b'
         ON w2.WidgetID = w1.WidgetID
ORDER  BY w1.WidgetID

#widgets2भीतर से जुड़ गया है #widgetProperties। उस ज्वाइन से होने वाली वर्चुअल टेबल लेफ्ट आउटर जॉइन में राइट हैंड टेबल है#widgets1

एक ही परिणाम एक व्युत्पन्न तालिका या सामान्य तालिका अभिव्यक्ति का उपयोग करके प्राप्त किया जा सकता है ...

WITH VT2
     AS (SELECT w2.WidgetID,
                w2.SomeValue,
                wp.PropertyName
         FROM   #widgets2 w2 
                JOIN #widgetProperties wp
                  ON w2.WidgetID = wp.WidgetID
                     AND wp.PropertyName = 'b')
SELECT w1.WidgetID,
       VT2.SomeValue,
       VT2.PropertyName
FROM   #widgets1 w1
       LEFT JOIN VT2
         ON VT2.WidgetID = w1.WidgetID
ORDER  BY w1.WidgetID 

... या वैकल्पिक रूप से आप वर्चुअल टेबल को फिर से ऑर्डर कर सकते हैं और RIGHT JOINइसके बजाय उपयोग कर सकते हैं।

SELECT w1.WidgetID,
       w2.SomeValue,
       wp.PropertyName
FROM   #widgets2 w2
       INNER JOIN #widgetProperties wp
               ON w2.WidgetID = wp.WidgetID
                  AND wp.PropertyName = 'b'
       RIGHT JOIN #widgets1 w1
               ON w2.WidgetID = w1.WidgetID
ORDER  BY w1.WidgetID 

यह यहाँ इत्ज़िक बेन गण द्वारा कवर किया गया है

... जॉय की शर्तों को तालिका क्रम में एक chiastic संबंध का पालन करना चाहिए। यदि आप टेबल T1, T2, T3 और T4 को उस क्रम में निर्दिष्ट करते हैं और JOIN की शर्तें T1 के साथ T2, T2 के साथ T3, और T4 के साथ T3 से मेल खाती हैं, तो आपको तालिका क्रम के विपरीत क्रम में JOIN की शर्तों को निर्दिष्ट करना होगा। , इस तरह:

FROM   T1
       <join_type> T2 T2
                  <join_type> T3 T3
                             <join_type> T4
                               ON T4.key = T3.key
                    ON T3.key = T2.key
         ON T2.key = T1.key 

इस जॉइन तकनीक को एक अलग तरीके से देखने के लिए, दी गई JOIN स्थिति केवल इसके ऊपर दी गई तालिका के नाम या तालिका के नामों को संदर्भित कर सकती है जो पहले की JOIN स्थितियों को पहले ही संदर्भित और हल कर चुके हैं।

लेकिन लेख में कई गलतियाँ हैं, साथ ही साथ लबोर कोलर द्वारा अनुवर्ती पत्र भी देखें।


धन्यवाद मार्टिन, यह उत्तर बहुत मददगार है। मैं हालांकि एक दूसरे को स्वीकार करूंगा, क्योंकि औपचारिक व्याकरण के बारे में उनकी बात से मुझे इस मुद्दे को पूरी तरह समझने में मदद मिली। विशेष रूप से "वर्णसंकर संबंध" एक गलत विचार है। यह एक पेड़ है, न कि सूची से उलट सूची। मस्टियाको ने यह समझने के लिए रूपरेखा प्रदान की कि इत्ज़िक व्याख्या क्यों सही नहीं है।
boot4life
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.