क्या SQL सर्वर GREATEST और LEAST का समर्थन करता है, यदि नहीं तो सामान्य वर्कअराउंड क्या है?


20

इस सवाल की समीक्षा करते हुए ऐसा लगता है कि यह बहुत काम है जिसकी आवश्यकता नहीं होनी चाहिए। वे एक तिथि के साथ एक सीमा का विस्तार करने की कोशिश कर रहे हैं। अन्य डेटाबेस में, आप बस का उपयोग करेंगे greatestऔर least..

least(extendDate,min), greatest(extendDate,max)

जब मैं इन का उपयोग करने की कोशिश करता हूं, तो मुझे मिलता है

'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.

यह दोनों दिशा में विस्तार को कवर करेगा।

प्रश्न के प्रयोजनों के लिए, आपको अभी भी विशेष श्रेणी प्रतिस्थापन करना होगा।

मैं सिर्फ यह सोच रहा हूं कि SQL सर्वर उपयोगकर्ता क्वेरी पैटर्न को किस प्रकार नकल leastऔर greatestकार्यक्षमता के लिए लागू करते हैं।

क्या आप CASEस्टेटमेंट में शर्तों को अनियंत्रित करते हैं या कोई एक्सटेंशन, थर्ड पार्टी ऐड-ऑन या Microsoft से लाइसेंस है जो इस कार्यक्षमता को सक्षम बनाता है?


2
feedback.azure.com/forums/908035-sql-server/suggestions/… यदि आप इसके लिए वोट करना चाहते हैं
J Brune

जवाबों:


33

एक सामान्य विधि VALUESक्लॉज का उपयोग करना है, और CROSS APPLYदो कॉलम एक ही कॉलम के रूप में अलियास किए गए हैं, फिर प्रत्येक का MINऔर प्राप्त करें MAX

SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM   dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );

उदाहरण के लिए, इसे लिखने के अन्य तरीके हैं UNION ALL

SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM   dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);

हालाँकि, परिणामी क्वेरी योजनाएँ समान प्रतीत होती हैं।



3

यह एक अच्छी शुरुआत होगी -

CASE WHEN A > B THEN A ELSE B END

यह एक अच्छा सुझाव है, लेकिन इस प्रश्न में "शर्त बयान में स्थिति को नियंत्रित करने" के साथ उल्लेख किया गया था
इवान कैरोल

3

समतुल्य बराबर:

IIF(@a < @b, @a, @b)

महान समकक्ष:

IIF(@a > @b, @a, @b)

3
आप इसे तीन या अधिक मूल्यों के लिए कैसे करते हैं, उदा least(5,6,7,8,9)?
a_horse_with_no_name

@a_horse_with_no_name नेस्टेड IIF का उपयोग करें
Elnur

यह दृष्टिकोण जल्दी से पढ़ने और सत्यापित करने के लिए चुनौतीपूर्ण हो जाएगा ... यह प्रदर्शन के मामले में कैसे किराया करता है?
डोडेकफोन

0

मैं उपयोगकर्ता-परिभाषित फ़ंक्शन बनाता हूं, उदाहरण के लिए

create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
  return case when @a <= @b then @a 
              when @b < @a  then @b
              else null
         end
end

हालाँकि यह साधारण मामलों में काम कर सकता है, लेकिन इस दृष्टिकोण के साथ कई मुद्दे हैं:

  • वार्षिक रूप से आपको प्रत्येक डेटा प्रकार के लिए अलग-अलग कार्य करने होंगे।
  • यह केवल 2 मापदंडों को संभालता है, इसलिए किसी को कई मापदंडों को संभालने या समान फ़ंक्शन के नेस्टेड कॉल का उपयोग करने के लिए अधिक फ़ंक्शन की आवश्यकता हो सकती है।
  • यह स्केलर फ़ंक्शन के बजाय इनलाइन TVF के रूप में बेहतर (अधिक कुशल) होगा। यह दिल में अदिश कार्यों के कार्यान्वयन के साथ करना है। इसके बारे में कई ब्लॉग हैं, उदाहरण के लिए देखें SQL 101: समानांतरवाद अवरोधक - स्केलर उपयोगकर्ता निर्धारित कार्य (जॉन केहियास द्वारा)
  • यदि कोई तर्क अशक्त है, तो यह अशक्त है। यह leastओरेकल और MySQL में ऑपरेटर के साथ क्या मेल खाता है , लेकिन पोस्टग्रेज से अलग है। लेकिन अशक्त के खिलाफ यह कवच इसे और अधिक क्रियाशील बनाता है (यदि आप जानते हैं कि वे अशक्त नहीं होंगे, तो एक सादा case when @a <= @b then @a else @b endकाम होगा)।

सभी के लिए यह बेहतर हो सकता है कि caseयदि कथन मायने रखता है तो स्टेटमेंट को लंबे समय तक लिखना बेहतर होगा । मैंने caseक्लाइंट पक्ष पर नेस्टेड स्टेटमेंट जेनरेट करने का भी सहारा लिया है जब तुलना करने के लिए कई मान हैं।


0

मैं @ ed-avis उत्तर में टिप्पणी जोड़ने का इरादा कर रहा था, लेकिन प्रतिष्ठा की कमी के कारण ऐसा करने में असमर्थ था, इसलिए इसे उनके उत्तर के विस्तार के रूप में पोस्ट कर रहा था।

मैंने "प्रत्येक डेटा प्रकार के लिए अलग-अलग कार्य करने के लिए" अनायास ही आप के नुकसान को समाप्त कर दिया है। SQL_VARIANT का उपयोग करना ।

यहाँ मेरा कार्यान्वयन है:

CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
  return case when @a <= @b then @a 
              when @b < @a  then @b
              WHEN @a IS NULL THEN @b
              WHEN @b IS NULL THEN @a
              else null
         end
END;

साथ ही यह फ़ंक्शन NULL को पोस्टग्रैस्कल संस्करण की तरह संभालता है

इस फ़ंक्शन को सुविधा के लिए DB में जोड़ा जा सकता है, लेकिन यह अंतर्निहित उपयोग की तुलना में 10 गुना धीमा है IIF। मेरे परीक्षण से पता चलता है कि सटीक प्रकार ( डेटाइम ) के साथ ऐसा कार्य sql_variant संस्करण के समान होता है ।

PS मैं 350k मानों के डेटा-सेट पर कुछ परीक्षण चलाता हूं, और ऐसा लगता है कि प्रदर्शन समान है, sql_variant थोड़ा तेज है, लेकिन मेरा मानना ​​है कि यह सिर्फ झटके है।

लेकिन किसी भी तरह से IIF संस्करण 10x गुना तेज है !!!

मैंने इनलाइन का परीक्षण नहीं किया है, CASE WHENलेकिन मूल रूप से t-sql IIF के मामले के समान है , और iif को केस एक्सप्रेशन के लिए ऑप्टिमाइज़र द्वारा परिवर्तित किया जाता है।

तथ्य यह है कि IIF का CASE में अनुवाद किया गया है, इस फ़ंक्शन के व्यवहार के अन्य पहलुओं पर भी प्रभाव पड़ता है।

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


LEAST () और GREATEST (), जब एक एसक्यूएल बोली में मौजूद होता है, तो एन कॉलम के बीच एक पंक्ति के भीतर परमिट की तुलना; मैंने एक समाधान के बाद ओपी को लिया जो समान परिणाम प्रदान करेगा। यहाँ उत्तर (कई अन्य लोगों के साथ) केवल 2 का समर्थन करता है
डोडेकफोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.