Database
 sql >> डेटाबेस >  >> RDS >> Database

पूर्ण जटिलताएँ - भाग 3, अनुपलब्ध मानक सुविधाएँ और T-SQL विकल्प

यह लेख NULL जटिलताओं पर एक श्रृंखला की तीसरी किस्त है। भाग 1 में मैंने NULL मार्कर का अर्थ और तुलना में यह कैसे व्यवहार करता है, को कवर किया। भाग 2 में मैंने विभिन्न भाषा तत्वों में NULL उपचार विसंगतियों का वर्णन किया है। इस महीने मैं शक्तिशाली मानक NULL हैंडलिंग सुविधाओं का वर्णन करता हूं जिन्हें अभी तक T-SQL में नहीं बनाया गया है, और उन वर्कअराउंड का जो लोग वर्तमान में उपयोग करते हैं।

मैं अपने कुछ उदाहरणों में पिछले महीने की तरह नमूना डेटाबेस TSQLV5 का उपयोग करना जारी रखूंगा। आप इस डेटाबेस को बनाने और भरने वाली स्क्रिप्ट यहां और इसके ईआर आरेख यहां पा सकते हैं।

DISTINCT विधेय

श्रृंखला के भाग 1 में मैंने समझाया कि कैसे एनयूएलएल तुलना में व्यवहार करते हैं और एसक्यूएल और टी-एसक्यूएल द्वारा नियोजित तीन-मूल्यवान विधेय तर्क के आसपास की जटिलताएं। निम्नलिखित विधेय पर विचार करें:

एक्स =वाई

यदि कोई विधेय NULL है - जिसमें दोनों NULL होने पर भी शामिल हैं - इस विधेय का परिणाम तार्किक मान UNKNOWN है। IS NULL और IS NOT NULL ऑपरेटरों के अपवाद के साथ, यह से भिन्न सहित अन्य सभी ऑपरेटरों पर भी लागू होता है। (<>):

एक्स <> वाई

अक्सर व्यवहार में आप चाहते हैं कि एनयूएलएल तुलनात्मक उद्देश्यों के लिए गैर-शून्य मानों की तरह व्यवहार करें। यह विशेष रूप से तब होता है जब आप उनका उपयोग अनुपलब्ध लेकिन अनुपयुक्त . का प्रतिनिधित्व करने के लिए करते हैं मूल्य। मानक के पास DISTINCT विधेय नामक एक विशेषता के रूप में इस आवश्यकता का समाधान है, जो निम्न प्रपत्र का उपयोग करता है:

IS [नहीं] . से अलग है

समानता या असमानता शब्दार्थ का उपयोग करने के बजाय, यह विधेय भविष्यवाणी की तुलना करते समय विशिष्टता-आधारित शब्दार्थ का उपयोग करता है। एक समानता ऑपरेटर (=) के विकल्प के रूप में, आप एक TRUE प्राप्त करने के लिए निम्न फॉर्म का उपयोग करेंगे, जब दो विधेय समान हों, जिसमें दोनों NULLs हों, और FALSE जब वे न हों, जिसमें कोई NULL हो और अन्य नहीं है:

X, Y से अलग नहीं है

से भिन्न . के विकल्प के रूप में ऑपरेटर (<>), आप एक TRUE प्राप्त करने के लिए निम्न फॉर्म का उपयोग करेंगे जब दो विधेय भिन्न होते हैं, जिसमें एक NULL होता है और दूसरा नहीं होता है, और FALSE जब वे समान होते हैं, जब दोनों NULL होते हैं:

X, Y से अलग है

आइए श्रृंखला में भाग 1 में हमारे द्वारा उपयोग किए गए उदाहरणों के लिए DISTINCT विधेय लागू करें। याद रखें कि आपको एक क्वेरी लिखने की आवश्यकता है जो एक इनपुट पैरामीटर देता है @dt रिटर्न ऑर्डर जो इनपुट तिथि पर शिप किए गए थे यदि यह गैर-नल है, या जो इनपुट न्यूल होने पर बिल्कुल भी शिप नहीं किया गया था। मानक के अनुसार, आप इस आवश्यकता को पूरा करने के लिए DISTINCT विधेय के साथ निम्नलिखित कोड का उपयोग करेंगे:

ऑर्डर आईडी चुनें, शिप की गई तारीख से बिक्री। ऑर्डर जहां शिप करने की तारीख @dt से अलग नहीं है;

अभी के लिए, भाग 1 से याद करें कि आप T-SQL में एक SARGable वर्कअराउंड के रूप में EXISTS विधेय और INTERSECT ऑपरेटर के संयोजन का उपयोग कर सकते हैं, जैसे:

सेलेक्ट ऑर्डरिड, शिपडडेटफ्रॉम सेल्स। ऑर्डर जहां मौजूद है (सिलेक्ट शिप डेट इंटरसेक्ट सेलेक्ट @डीटी);

उन आदेशों को वापस करने के लिए जो इनपुट तिथि @dt से अलग (अलग) तारीख पर भेजे गए थे, आप निम्न क्वेरी का उपयोग करेंगे:

आदेश चुनें, शिप की गई तारीख से बिक्री। ऑर्डर जहां शिप की गई तारीख @dt से अलग है;

टी-एसक्यूएल में काम करने वाला वर्कअराउंड EXISTS विधेय और EXCEPT ऑपरेटर के संयोजन का उपयोग करता है, जैसे:

सेलेक्ट ऑर्डर आईडी, शिपडडेटफ्रॉम सेल्स। ऑर्डर जहां मौजूद है (सेलेक्ट शिप डेट को छोड़कर सेलेक्ट @डीटी);

भाग 1 में मैंने उन परिदृश्यों पर भी चर्चा की जहां आपको तालिकाओं में शामिल होने की आवश्यकता होती है और शामिल होने की भविष्यवाणी में विशिष्टता-आधारित शब्दार्थ लागू करने की आवश्यकता होती है। मेरे उदाहरणों में मैंने T1 और T2 नामक तालिकाओं का उपयोग किया, जिसमें दोनों पक्षों में k1, k2 और k3 नामक न्यूलेबल जॉइन कॉलम थे। मानक के अनुसार, आप इस तरह के जुड़ाव को संभालने के लिए निम्नलिखित कोड का उपयोग करेंगे:

चुनें T1.k1, T1.K2, T1.K3, T1.val1, T2.val2FROM dbo.T1INNER जॉइन dbo.T2 ON T1.k1 T2.k1 से अलग नहीं है और T1.k2 T2 से अलग नहीं है .k2 और T1.k3 T2.k3 से अलग नहीं हैं;

अभी के लिए, पिछले फ़िल्टरिंग कार्यों के समान, आप T-SQL में विशिष्ट विधेय का अनुकरण करने के लिए शामिल होने के ON क्लॉज़ में EXISTS विधेय और INTERSECT ऑपरेटर के संयोजन का उपयोग कर सकते हैं, जैसे:

चुनें T1.k1, T1.K2, T1.K3, T1.val1, T2.val2FROM dbo.T1INNER जॉइन डीबीओ। , T2.k2, T2.k3);

जब फ़िल्टर में उपयोग किया जाता है, तो यह फ़ॉर्म SARGable होता है, और जब जॉइन में उपयोग किया जाता है, तो यह फ़ॉर्म संभावित रूप से अनुक्रमणिका क्रम पर भरोसा कर सकता है।

यदि आप T-SQL में जोड़ा गया DISTINCT विधेय देखना चाहते हैं, तो आप इसके लिए यहां वोट कर सकते हैं।

यदि इस खंड को पढ़ने के बाद भी आप DISTINCT विधेय के बारे में थोड़ा असहज महसूस करते हैं, तो आप अकेले नहीं हैं। शायद यह विधेय वर्तमान में हमारे पास टी-एसक्यूएल में मौजूद किसी भी मौजूदा कामकाज से काफी बेहतर है, लेकिन यह थोड़ा वर्बोज़ और थोड़ा भ्रमित करने वाला है। यह हमारे दिमाग में सकारात्मक तुलना को लागू करने के लिए एक नकारात्मक रूप का उपयोग करता है, और इसके विपरीत। खैर, किसी ने नहीं कहा कि सभी मानक सुझाव सही हैं। जैसा कि चार्ली ने भाग 1 में अपनी एक टिप्पणी में उल्लेख किया है, निम्नलिखित सरलीकृत रूप बेहतर काम करेगा:

IS [नहीं]

यह संक्षिप्त और बहुत अधिक सहज है। X के बजाय Y से अलग नहीं है, आप इसका उपयोग करेंगे:

एक्स आईएस वाई

और X के बजाय Y से अलग है, आप इसका उपयोग करेंगे:

एक्स वाई नहीं है

यह प्रस्तावित ऑपरेटर वास्तव में पहले से मौजूद IS NULL और IS NOT NULL ऑपरेटरों के साथ संरेखित है।

हमारे क्वेरी कार्य के लिए लागू, इनपुट तिथि पर शिप किए गए ऑर्डर वापस करने के लिए (या यदि इनपुट न्यूल है तो शिप नहीं किया गया था) आप निम्न कोड का उपयोग करेंगे:

आदेश चुनें, शिप की गई तारीख से बिक्री। ऑर्डर जहां शिप की गई तारीख IS @dt;

इनपुट तिथि से भिन्न दिनांक को शिप किए गए ऑर्डर वापस करने के लिए आप निम्न कोड का उपयोग करेंगे:

सेलेक्ट ऑर्डर आईडी, शिपडेट से बिक्री। ऑर्डर जहां शिप की गई तारीख @dt नहीं है;

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

नल ट्रीटमेंट क्लॉज (IGNORE NULLS | RESPECT NULLS)

ऑफ़सेट विंडो फ़ंक्शन LAG, LEAD, FIRST_VALUE और LAST_VALUE का उपयोग करते समय, कभी-कभी आपको NULL उपचार व्यवहार को नियंत्रित करने की आवश्यकता होती है। डिफ़ॉल्ट रूप से, ये फ़ंक्शन अनुरोधित स्थिति में अनुरोधित अभिव्यक्ति का परिणाम लौटाते हैं, भले ही अभिव्यक्ति का परिणाम वास्तविक मान या NULL हो। हालांकि, कभी-कभी आप प्रासंगिक दिशा में आगे बढ़ना जारी रखना चाहते हैं, (LAG और LAST_VALUE के लिए पिछड़ा, LEAD और FIRST_VALUE के लिए आगे), और यदि मौजूद हो तो पहला गैर-नल मान लौटाएं, और अन्यथा NULL। मानक आपको NULL उपचार खंड . का उपयोग करके इस व्यवहार पर नियंत्रण प्रदान करता है निम्नलिखित सिंटैक्स के साथ:

ऑफसेट_फंक्शन (<अभिव्यक्ति>) IGNORE_NULLS | सम्मान नल खत्म (<विंडो विनिर्देश>)

यदि NULL उपचार खंड निर्दिष्ट नहीं है, तो डिफ़ॉल्ट RESPECT NULLS विकल्प है, जिसका अर्थ है कि जो कुछ भी अनुरोधित स्थिति में मौजूद है, भले ही NULL हो। दुर्भाग्य से, यह खंड अभी तक टी-एसक्यूएल में उपलब्ध नहीं है। मैं LAG और FIRST_VALUE फ़ंक्शंस के साथ-साथ टी-एसक्यूएल में काम करने वाले वर्कअराउंड का उपयोग करके मानक सिंटैक्स के लिए उदाहरण प्रदान करूंगा। यदि आपको LEAD और LAST_VALUE के साथ ऐसी कार्यक्षमता की आवश्यकता है, तो आप समान तकनीकों का उपयोग कर सकते हैं।

नमूना डेटा के रूप में मैं T4 नामक एक तालिका का उपयोग करूंगा जिसे आप निम्न कोड का उपयोग करके बनाते और पॉप्युलेट करते हैं:

 ड्रॉप टेबल अगर मौजूद है dbo.T4; GO क्रिएट टेबल dbo.T4 (आईडी नॉट नॉट न्यूल कॉन्स्ट्रेंट PK_T4 प्राथमिक कुंजी, col1 INT NULL); dbo.T4(id, col1) VALUES( 2, NULL),(3, 10),(5, -1),( 7, NULL),(11, NULL),(13, -12),( 17, NULL),(19, NULL),(23, 1759);

एक सामान्य कार्य है जिसमें अंतिम प्रासंगिक . को वापस करना शामिल है मूल्य। Col1 में एक NULL मान में कोई परिवर्तन नहीं दर्शाता है, जबकि एक गैर-NULL मान एक नए प्रासंगिक मान को इंगित करता है। आपको आईडी क्रम के आधार पर अंतिम गैर-नल col1 मान वापस करना होगा। मानक NULL उपचार खंड का उपयोग करके, आप कार्य को इस प्रकार संभालेंगे:

सिलेक्ट आईडी, col1,COALESCE(col1, LAG(col1) IGNORE NULLS OVER(id by order)) as lastvalFROM dbo.T4;

यहाँ इस क्वेरी से अपेक्षित आउटपुट दिया गया है:

id col1 lastval-------------------------------------------2 NULL3 10 105-1 -17 NULL - 111 NULL -113 -12 -1217 NULL -1219 NULL -1223 1759 1759

T-SQL में वर्कअराउंड है, लेकिन इसमें विंडो फ़ंक्शन की दो परतें और एक टेबल एक्सप्रेशन शामिल है।

पहले चरण में, जब col1 NULL नहीं है, तब तक आप अधिकतम id मान रखने वाले grp नामक कॉलम की गणना करने के लिए MAX विंडो फ़ंक्शन का उपयोग करते हैं, जैसे:

सिलेक्ट आईडी, col1,MAX(केस जब col1 नहीं है तब आईडी END) ओवर (आईडी ROWS अनबाउंडेड प्रीसीडिंग के अनुसार ऑर्डर) grpFROM dbo.T4 के रूप में;

यह कोड निम्न आउटपुट उत्पन्न करता है:

आईडी col1 जीआरपी ----------- ---------------------------2 NULL3 10 35 -1 57 NULL 511 NULL 513 -12 1317 NULL 1319 NULL 1323 1759 23

जैसा कि आप देख सकते हैं, जब भी col1 मान में कोई परिवर्तन होता है तो एक अद्वितीय जीआरपी मान बनाया जाता है।

दूसरे चरण में आप पहले चरण की क्वेरी के आधार पर एक सीटीई परिभाषित करते हैं। फिर, बाहरी क्वेरी में आप जीआरपी द्वारा परिभाषित प्रत्येक विभाजन के भीतर अब तक का अधिकतम col1 मान लौटाते हैं। वह अंतिम गैर-नल col1 मान है। यहां संपूर्ण समाधान कोड दिया गया है:

C AS के साथ (सिलेक्ट आईडी, col1, MAX (केस जब col1 न्यूल नहीं है तब आईडी END) ओवर (आईडी पंक्तियों द्वारा ऑर्डर अनबाउंडेड प्रीसीडिंग) dbo.T4 से जीआरपी के रूप में) चयन आईडी, col1, MAX (col1) ओवर ( आईडी पंक्तियों के आधार पर समूह क्रम से विभाजन असंबद्ध पूर्ववर्ती) अंतिम के रूप मेंसी से;

स्पष्ट रूप से, यह केवल IGNORE_NULLS कहने की तुलना में बहुत अधिक कोड और कार्य है।

एक और आम जरूरत पहले प्रासंगिक मूल्य को वापस करने की है। हमारे मामले में, मान लीजिए कि आपको आईडी क्रम के आधार पर अब तक का पहला गैर-नल col1 मान वापस करने की आवश्यकता है। मानक NULL उपचार खंड का उपयोग करके, आप FIRST_VALUE फ़ंक्शन और IGNORE NULLS विकल्प के साथ कार्य को संभालेंगे, जैसे:

चयन आईडी, col1,FIRST_VALUE(col1) IGNORE NULLS OVER(Id ROWS अनबाउंडेड प्रीसीडिंग के अनुसार ऑर्डर करें) पहलेvalFROM dbo.T4 से;

यहाँ इस क्वेरी से अपेक्षित आउटपुट दिया गया है:

आईडी col1 प्रथम---------------------------------------2 NULL3 10 105 -1 107 NULL 1011 NULL 1013 -12 1017 न्यूल 1019 न्यूल 1023 1759 10

टी-एसक्यूएल में वर्कअराउंड पिछले गैर-शून्य मान के लिए उपयोग की जाने वाली एक समान तकनीक का उपयोग करता है, केवल डबल-मैक्स दृष्टिकोण के बजाय, आप मिन फ़ंक्शन के शीर्ष पर FIRST_VALUE फ़ंक्शन का उपयोग करते हैं।

पहले चरण में, आप जीआरपी नामक कॉलम की गणना करने के लिए मिन विंडो फ़ंक्शन का उपयोग करते हैं, जो अब तक न्यूनतम आईडी मान रखता है, जब col1 NULL नहीं है, जैसे:

सिलेक्ट आईडी, col1, MIN(केस जब col1 नहीं है तो आईडी END) ओवर (आईडी ROWS अनबाउंडेड प्रीसीडिंग के अनुसार ऑर्डर) grpFROM dbo.T4 के रूप में;

यह कोड निम्न आउटपुट उत्पन्न करता है:

आईडी col1 जीआरपी ----------- ---------------------------2 NULL3 10 35 -1 37 NULL 311 NULL 313 -12 317 NULL 319 NULL 323 1759 3

यदि पहले प्रासंगिक मान से पहले कोई एनयूएलएल मौजूद है तो आप दो समूहों के साथ समाप्त होते हैं-पहला जीआरपी मान के रूप में न्यूल के साथ और दूसरा गैर-नल आईडी के साथ जीआरपी मान के रूप में।

दूसरे चरण में आप पहले चरण के कोड को तालिका व्यंजक में रखते हैं। फिर बाहरी क्वेरी में आप FIRST_VALUE फ़ंक्शन का उपयोग करते हैं, जिसे grp द्वारा विभाजित किया जाता है, यदि मौजूद हो तो पहला प्रासंगिक (गैर-NULL) मान एकत्र करने के लिए, और NULL अन्यथा, जैसे:

सी एएस के साथ (चयन आईडी, कॉल 1, मिन (केस जब कॉल 1 शून्य नहीं है तो आईडी समाप्त) ओवर (आईडी पंक्तियों द्वारा ऑर्डर अनबाउंडेड प्रीसिडिंग) डीबीओ से जीआरपी के रूप में। टी 4) आईडी चुनें, कॉल 1, FIRST_VALUE (col1) ओवर ( आईडी पंक्तियों के आधार पर समूह क्रम से विभाजन असंबद्ध पूर्ववर्ती) पहले के रूप मेंसी से;

फिर से, IGNORE_NULLS विकल्प का उपयोग करने की तुलना में यह बहुत अधिक कोड और कार्य है।

अगर आपको लगता है कि यह सुविधा आपके लिए उपयोगी हो सकती है, तो आप यहां टी-एसक्यूएल में शामिल करने के लिए वोट कर सकते हैं।

NULLS द्वारा पहले ऑर्डर करें | नल अंतिम

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

आदेश का चयन करें, बिक्री की तारीख से भेज दिया गया है। 

यह क्वेरी निम्न आउटपुट उत्पन्न करती है:

आदेश शिप करने की तिथि ----------- -----------11008 NULL11019 NULL11039 NULL...10249 2017-07-1010252 2017-07-1110250 2017-07-12 ...11063 2019-05-0611067 2019-05-0611069 2019-05-06

आउटपुट से पता चलता है कि शिप न किए गए ऑर्डर, जिनकी शिप की गई तारीख NULL है, शिप किए गए ऑर्डर से पहले के ऑर्डर, जिनकी मौजूदा लागू शिप की गई तारीख है।

लेकिन क्या होगा यदि आरोही क्रम का उपयोग करते समय आपको अंतिम ऑर्डर करने के लिए एनयूएलएल की आवश्यकता हो? ISO/IEC SQL मानक एक क्लॉज का समर्थन करता है जिसे आप एक ऑर्डरिंग एक्सप्रेशन पर लागू करते हैं जो यह नियंत्रित करता है कि NULLs पहले ऑर्डर करता है या आखिरी। इस क्लॉज का सिंटैक्स है:

<ऑर्डरिंग एक्सप्रेशन> NULLS FIRST | नल अंतिम

हमारी ज़रूरतों को पूरा करने के लिए, उनकी शिप की गई तारीखों के आधार पर क्रमबद्ध ऑर्डर लौटाना, आरोही, लेकिन अनशिप किए गए ऑर्डर के साथ आखिरी बार लौटा, और फिर उनके ऑर्डर आईडी द्वारा टाईब्रेकर के रूप में, आप निम्न कोड का उपयोग करेंगे:

आदेश चुनें, शिप की गई तारीख से बिक्री। 

दुर्भाग्य से, यह NULLS ऑर्डरिंग क्लॉज T-SQL में उपलब्ध नहीं है।

टी-एसक्यूएल में लोगों द्वारा उपयोग किया जाने वाला एक सामान्य कामकाज एक केस अभिव्यक्ति के साथ ऑर्डरिंग अभिव्यक्ति से पहले होता है जो एनयूएलएल की तुलना में गैर-नल मानों के लिए कम ऑर्डरिंग मान के साथ स्थिरांक देता है, जैसे (हम इस समाधान को क्वेरी 1 कहते हैं):

आदेश का चयन करें, शिप की गई तारीख से बिक्री। आदेश के अनुसार आदेश जब शिप की गई तारीख शून्य नहीं है तो 0 ईएलएसई 1 समाप्त, शिप की गई तारीख, ऑर्डर आईडी;

यह क्वेरी एनयूएलएल के साथ वांछित आउटपुट उत्पन्न करती है जो आखिरी बार दिखाई देती है:

आदेश शिप करने की तिथि--------------------10249 2017-07-1010252 2017-07-1110250 2017-07-12...11063 2019-05 -0611067 2019-05-0611069 2019-05-0611008 NULL11019 NULL11039 NULL...

Sales.Orders तालिका पर एक कवरिंग इंडेक्स परिभाषित किया गया है, जिसमें कुंजी के रूप में शिपडडेट कॉलम है। हालाँकि, जिस तरह से एक हेरफेर फ़िल्टरिंग कॉलम फ़िल्टर की SARGability और एक इंडेक्स को लागू करने की क्षमता को रोकता है, उसी तरह एक हेरफेर ऑर्डरिंग कॉलम क्वेरी के ORDER BY क्लॉज का समर्थन करने के लिए इंडेक्स ऑर्डरिंग पर भरोसा करने की क्षमता को रोकता है। इसलिए, SQL सर्वर एक स्पष्ट सॉर्ट ऑपरेटर के साथ क्वेरी 1 के लिए एक योजना तैयार करता है, जैसा कि चित्र 1 में दिखाया गया है।

चित्र 1:प्रश्न 1 के लिए योजना

कभी-कभी डेटा का आकार इतना बड़ा नहीं होता है कि स्पष्ट छँटाई एक समस्या हो। लेकिन कभी-कभी ऐसा होता है। स्पष्ट छँटाई के साथ क्वेरी की मापनीयता अतिरिक्त-रैखिक हो जाती है (आपके पास जितनी अधिक पंक्तियाँ हैं, आप प्रति पंक्ति अधिक भुगतान करते हैं), और प्रतिक्रिया समय (पहली पंक्ति को वापस करने में लगने वाला समय) में देरी होती है।

एक तरकीब है जिसका उपयोग आप ऐसे मामले में स्पष्ट छँटाई से बचने के लिए कर सकते हैं, एक समाधान के साथ जो एक ऑर्डर-संरक्षण मर्ज जॉइन कॉन्सटेनेशन ऑपरेटर का उपयोग करके अनुकूलित हो जाता है। आप SQL सर्वर में विभिन्न परिदृश्यों में नियोजित इस तकनीक का विस्तृत कवरेज पा सकते हैं:मर्ज जॉइन कॉन्सटेनेशन के साथ सॉर्ट से बचना। समाधान में पहला चरण दो प्रश्नों के परिणामों को एकीकृत करता है:एक क्वेरी उन पंक्तियों को लौटाती है जहां ऑर्डरिंग कॉलम NULL नहीं है, जिसके परिणामस्वरूप कुछ ऑर्डरिंग मान के साथ स्थिरांक के आधार पर परिणाम कॉलम (हम इसे सॉर्टकोल कहते हैं), 0 कहते हैं, और एनयूएलएल के साथ पंक्तियों को वापस करने वाली एक और क्वेरी, सॉर्टकोल को पहली क्वेरी की तुलना में उच्च ऑर्डरिंग मान के साथ स्थिर पर सेट किया गया है, 1 कहें। दूसरे चरण में आप पहले चरण से कोड के आधार पर एक टेबल अभिव्यक्ति परिभाषित करते हैं, और फिर बाहरी क्वेरी में आप टेबल एक्सप्रेशन से पंक्तियों को पहले सॉर्टकोल द्वारा, और फिर शेष ऑर्डरिंग तत्वों द्वारा ऑर्डर करते हैं। इस तकनीक को लागू करने वाले संपूर्ण समाधान का कोड यहां दिया गया है (हम इस समाधान को प्रश्न 2 कहेंगे):

सी एएस के साथ (सेलेक्ट ऑर्डरिड, शिपडेट, 0 एएस सॉर्टकॉल से बिक्री। ऑर्डर जहां शिप की गई तारीख न्यूल यूनियन नहीं है सभी सेलेक्ट ऑर्डरआईडी, शिप की गई तारीख, 1 बिक्री से सॉर्टकॉल के रूप में। ऑर्डर जहां शिप की गई तारीख न्यूल है) ऑर्डरिड का चयन करें, सॉर्टकोल, शिपडेट, ऑर्डरिड द्वारा कॉर्डर से शिप किया गया।;

इस क्वेरी की योजना चित्र 2 में दिखाई गई है।

चित्र 2:क्वेरी 2 के लिए योजना

कवरिंग इंडेक्स idx_nc_shippeddate में दो तलाश और ऑर्डर किए गए रेंज स्कैन पर ध्यान दें—एक उन पंक्तियों को खींच रहा है जहां शिपडेटिस न्यूल नहीं है और दूसरी पुलिंग पंक्तियां जहां शिपडेट न्यूल है। फिर, जिस तरह से मर्ज जॉइन एल्गोरिथम एक जॉइन में काम करता है, उसी तरह मर्ज जॉइन (कॉन्सटेनेशन) एल्गोरिथम दो ऑर्डर किए गए पक्षों की पंक्तियों को एक ज़िपर की तरह से एकीकृत करता है, और क्वेरी की प्रेजेंटेशन ऑर्डरिंग जरूरतों का समर्थन करने के लिए अंतर्ग्रहीत ऑर्डर को संरक्षित करता है। मैं यह नहीं कह रहा हूं कि यह तकनीक CASE अभिव्यक्ति के साथ अधिक विशिष्ट समाधान की तुलना में हमेशा तेज होती है, जो स्पष्ट छँटाई को नियोजित करती है। हालाँकि, पूर्व में रैखिक स्केलिंग है और बाद वाले में n लॉग n स्केलिंग है। तो पहले वाले को बड़ी संख्या में पंक्तियों के साथ और बाद वाले को छोटी संख्याओं के साथ बेहतर करने की प्रवृत्ति होगी।

स्पष्ट रूप से इस सामान्य आवश्यकता के लिए एक समाधान होना अच्छा है, लेकिन यह बहुत बेहतर होगा यदि T-SQL ने भविष्य में मानक NULL ऑर्डरिंग क्लॉज के लिए समर्थन जोड़ा।

निष्कर्ष

ISO/IEC SQL मानक में बहुत सारी NULL हैंडलिंग सुविधाएँ हैं जो अभी तक T-SQL में नहीं आई हैं। इस लेख में मैंने उनमें से कुछ को कवर किया:DISTINCT विधेय, NULL उपचार खंड, और यह नियंत्रित करना कि क्या NULLs पहले या अंतिम आदेश देता है। मैंने इन सुविधाओं के लिए वर्कअराउंड भी प्रदान किए हैं जो टी-एसक्यूएल में समर्थित हैं, लेकिन वे स्पष्ट रूप से बोझिल हैं। अगले महीने मैं मानक अद्वितीय बाधा को कवर करके चर्चा जारी रखता हूं, यह टी-एसक्यूएल कार्यान्वयन और टी-एसक्यूएल में लागू किए जा सकने वाले कामकाज से कैसे अलग है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. TimescaleDB के लिए बैकअप प्रबंधन युक्तियाँ

  2. एसक्यूएल मिन () शुरुआती के लिए

  3. टी-एसक्यूएल क्या है?

  4. मौसम ऐप के लिए डेटा मॉडल

  5. डेटा कैटलॉग, व्यावसायिक शब्दावलियों और डेटा शासन के माध्यम से ग्राहक व्यवसाय इंटेलिजेंस सक्षम करें