SQL सर्वर में अधिकतम फ़ंक्शन है जो .NET में Math.Max ​​जैसे दो मान लेता है?


488

मैं इस तरह से एक प्रश्न लिखना चाहता हूं:

SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o

लेकिन यह नहीं है कि MAXफ़ंक्शन कैसे काम करता है? यह एक समग्र कार्य है इसलिए यह एकल पैरामीटर की अपेक्षा करता है और फिर सभी पंक्तियों के MAX को लौटाता है।

क्या कोई जानता है कि यह मेरा तरीका कैसे है?


13
यह GREATESTफ़ंक्शन के रूप में अधिकांश अन्य डेटाबेस में लागू किया गया है; SQLite MAXकुल में कई कॉलम की अनुमति देकर समर्थन का अनुकरण करता है ।
OMG पॉनीज़

7
के संभावित डुप्लिकेट stackoverflow.com/questions/71022/sql-max-of-multiple-columns
माइकल Freidgeim

नीचे दिए गए अधिकतम (ए, बी) के लिए एक समाधान खोजते समय, इस सवाल को ध्यान में रखें कि क्या आप "ए" और / या "बी" के लिए वाक्यविन्यास या गणना को दोहराया जाना चाहते हैं। Ie यदि "b" एक जटिल गणना से लिया गया है जिसमें बहुत सारे वाक्यविन्यास शामिल हैं तो आप एक समाधान पसंद कर सकते हैं जहां "b" केवल एक बार दिखाई देता है। उदाहरण के लिए "आईआईएफ (ए> बी, ए, बी)" का अर्थ है "बी" को दोहराना - जो कि वाक्यविन्यास रूप से बदसूरत हो सकता है, हालांकि निम्नलिखित समाधान का अर्थ है "बी" (और "ए" केवल एक बार दिखाई देते हैं: मैक्स (वैल्यू) चुनें FROM (AS AS VALUE UNION SELECT b AS VALUE के रूप में चयन करें) T1 के रूप में
एंड्रयू जेन्स

जवाबों:


158

User-Defined Functionयदि आप अपने उदाहरण के समान वाक्यविन्यास करना चाहते हैं तो आपको यह करने की आवश्यकता होगी , लेकिन क्या आप ऐसा कर सकते हैं जो इनलाइन करना चाहते हैं, इनलाइन, एक CASEबयान के साथ आसानी से , जैसा कि अन्य ने कहा है।

UDFकुछ इस तरह हो सकता है:

create function dbo.InlineMax(@val1 int, @val2 int)
returns int
as
begin
  if @val1 > @val2
    return @val1
  return isnull(@val2,@val1)
end

... और आप इसे ऐसे ही कहेंगे ...

SELECT o.OrderId, dbo.InlineMax(o.NegotiatedPrice, o.SuggestedPrice) 
FROM Order o

24
मैं आपको समाधान का समर्थन करूंगा, केवल एक चीज जो मैं जोड़ूंगा वह है NULL मानों का समर्थन। यदि आप केवल अंतिम पंक्ति को संशोधित करते हैं: "वापसी @ value2" को इस रूप में पढ़ने के लिए: "वापसी isnull (@ val2, @ val1)" तो यदि कोई मान शून्य है तो फ़ंक्शन शून्य मान लौटाएगा, अन्यथा यह इस तरह काम करेगा सामान्य
क्रिस्तोफ़

1
अन्य डेटा प्रकारों के बारे में क्या है? क्या मुझे एक हायरइन्तेर्गर आर्गुमेंट और हायरटेटटाइमएरगमेंट और हायरवार्चर आर्गुमेंट और ए ... लिखना होगा?
onayaywhen

9
यह अविश्वसनीय रूप से धीमा होगा, क्योंकि सभी चीजें स्केलर यूडीएफ हैं। उपयोग इनलाइन UDFs बजाय
एके

12
@xan मेरे पास कोई सुराग नहीं है जो मेरे दिमाग से गुजरे जब मैंने वास्तव में उस प्रश्न को पूछा था। बहुत ज्यादा नहीं, जाहिर है। वैसे भी उत्तर के लिए धन्यवाद।
थॉमस

13
@ थोमस अप्रचलित मेम छवि (किसी भी तरह से आपका कोई इरादा नहीं!) Flickr.com/photos/16201371@N00/2375571206
xan

467

यदि आप SQL Server 2008 (या ऊपर) का उपयोग कर रहे हैं, तो यह बेहतर उपाय है:

SELECT o.OrderId,
       (SELECT MAX(Price)
        FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price))
FROM Order o

सभी क्रेडिट और वोटों को स्वेन के संबंधित प्रश्न पर जाना चाहिए , "कई कॉलम का एसक्यूएल मैक्स?"
मैं कहता हूं कि यह " सबसे अच्छा जवाब " है क्योंकि:

  1. इसे UNION's, PIVOT's, UNPIVOT's, UDF's और क्रेजी-लॉन्ग CASE स्टैच्यूज़ के साथ अपने कोड को जटिल करने की आवश्यकता नहीं है।
  2. यह नल से निपटने की समस्या से ग्रस्त नहीं है, यह उन्हें ठीक से संभालता है।
  3. "MIN", "AVG", या "SUM" के साथ "MAX" को स्वैप करना आसान है। आप कई अलग-अलग स्तंभों पर कुल को खोजने के लिए किसी भी समुच्चय फ़ंक्शन का उपयोग कर सकते हैं।
  4. आप मेरे द्वारा उपयोग किए जाने वाले नामों (यानी "AllPrices" और "Price") तक सीमित नहीं हैं। अगले आदमी के लिए पढ़ना और समझना आसान बनाने के लिए आप अपने खुद के नाम चुन सकते हैं।
  5. आप SQL Server 2008 के व्युत्पन्न_तबलों का उपयोग करके कई समुच्चय पा सकते हैं जैसे:
    SELECT MAX (a), MAX (b) FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10)) माईटेबल (ए, बी) के रूप में

27
+1 केवल एक उत्तर है जिसके लिए प्रक्रिया / कार्य करने की आवश्यकता नहीं है!
एलेक्स

6
बिल्कुल उसी प्रकार का उत्तर जिसकी मुझे तलाश थी। फ़ंक्शंस का उपयोग धीमा है और यह तिथियों पर भी काम करेगा, जो मुझे चाहिए।
जोहान स्ट्राइडम

3
+1 सही काम करता है, विशेष रूप से 2 से अधिक स्तंभों की तुलना करने के लिए!
JanW

11
यह CASE WHEN सॉल्यूशन से कम परफ़ॉर्मर है जिसे केवल एक स्केलर की गणना करने की आवश्यकता है।
टेकुमरा

5
जबकि सरल सिंटैक्स 2 मानों के MAX का निर्धारण करते समय प्रदर्शन हिट के लायक कभी नहीं हो सकता है, यह अधिक मूल्यों के साथ एक अलग मामला हो सकता है। 4 मानों का MAX प्राप्त करने पर भी CASE क्लॉज़ लंबे समय तक बने रहते हैं, अगर हाथ से उत्पन्न होने वाली त्रुटि सरल और स्पष्ट रहती है, तो अनाड़ी और त्रुटि हो जाती है।
टाइफोलोसॉरस

220

एक लाइन में किया जा सकता है:

-- the following expression calculates ==> max(@val1, @val2)
SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2)) 

संपादित करें: यदि आप बहुत बड़ी संख्या के साथ काम कर रहे हैं तो पूर्णांक अतिप्रवाह से बचने के लिए आपको मूल्य चर को बिगिन में बदलना होगा।


18
+1 मेरा मानना ​​है कि आपने सबसे सही तरीका प्रदान किया है। "SELECT ((@ val1 + @ val2) + ABS (@ val1- @ val2)) / 2 को MAX_OF_TWO के रूप में" याद रखें, "SELECT ((@ val1 + @ val2) - ABS (@ val1 (@ val2)) / 2 MIN_OF_TWO के रूप में "।
टॉम

6
इस तरह से एक अतिप्रवाह त्रुटि देगा यदि राशि एक इंट में अधिक से अधिक हो सकती है: @ @ घोषणा करें @ val1 int घोषणा @ val2 int सेट @ val1 = 1500000000 सेट @ val2 = 1500000000 चयन 0.5 * (@ val1 + @ val2) + ABS (@ val1 - @ val2)) - => अतिप्रवाह त्रुटि
आकाशवाणी

89
यह अत्यंत "गंदा" "चाल" है। जब आपके कोड को प्रोग्रामिंग करना स्पष्ट रूप से उद्देश्य को व्यक्त करना चाहिए, हालांकि आपके मामले में ऐसा लगता है कि ओफिसकेशन प्रतियोगिता से लिया गया कोड।
ग्रीनल्डमैन

24
यह "गंदा" हो सकता है, लेकिन यह सरल SQL बोलियों वाले डेटाबेस के लिए एकमात्र विकल्प हो सकता है।
splattne

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

127

मुझे ऐसा नहीं लगता। मैं दूसरे दिन यही चाहता था। मुझे जो निकटतम मिला वह था:

SELECT
  o.OrderId,
  CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN o.NegotiatedPrice 
     ELSE o.SuggestedPrice
  END
FROM Order o

4
यह मेरी पसंदीदा विधि है। आप एक अतिप्रवाह का जोखिम नहीं उठाते हैं, और यह splattne के समाधान (जो शांत btw है) की तुलना में कम गूढ़ है, और मुझे UDF बनाने का झंझट नहीं है। कई स्थितियों में मामला बहुत आसान है।
लांस फिशर

SELECT o.OrderId, CASE WHEN o.NegotiatedPrice> o.SuggestedPrice OR o.SuggestedPrice IS NULL THEN o.NegotiatedPrice ELSE o.SuggestedPrice END FROM Order o
mohghaderi

जब "o.NegotiatedPrice" के बजाय आपके पास एक शब्द होता है जैसे "(datediff (दिन, कन्वर्ट (डेटाटाइम, adr_ogn_since, 120), getdate) ()) - 5) * 0.3" आपको इस कोड को दोहराना होगा। भविष्य में शब्द में कोई भी परिवर्तन दो बार किया जाना है। एक मिनट (x, y, ...) प्रकार फ़ंक्शन बहुत अच्छा होगा
डैनियल

87

IIF फ़ंक्शन की कोशिश क्यों न करें (SQL Server 2012 और बाद की आवश्यकता है)

IIF(a>b, a, b)

बस।

(संकेत: या तो इसके बारे में सावधान रहें null, क्योंकि a>bजब भी अशक्त होगा , तब परिणाम गलत bहोगा । इसलिए इस परिणाम में परिणाम होगा)


7
यदि मूल्यों में से एक है NULL, तो परिणाम हमेशा दूसरा होगा।
जाहू

4
IIF () CASE स्टेटमेंट के लिए सिंटैक्टिक शुगर है। यदि CASE सशर्त का कोई भी मान NULL है, तो परिणाम दूसरा (ELSE) होगा।
xxyzzy

@xxyzzy क्योंकि NULL > 1234बयान गलत है
शिन

8
इसलिए IIF(a>b, a, COALESCE(b,a))केवल एक ही मौजूद होने पर मूल्य देने के लिए
एमपाग

32
DECLARE @MAX INT
@MAX = (SELECT MAX(VALUE) 
               FROM (SELECT 1 AS VALUE UNION 
                     SELECT 2 AS VALUE) AS T1)

मैं इस समाधान को एक +1 देता हूं क्योंकि यह एक UDF लिखने की आवश्यकता के बिना DRY (खुद को दोहराना नहीं) के अनुरूप है। यह भी बहुत अच्छा है अगर आपके द्वारा जांचे जाने वाले दोनों मान अन्य sql के परिणाम हैं, उदाहरण के लिए मेरे मामले में मैं 2 चुनिंदा गिनती (*) कथनों में से अधिक से अधिक खोजना चाहता हूं।
मिकुल्ल्स

1
मुझे नफरत है कि मुझे इस समाधान का सहारा लेना है, लेकिन यह सुनिश्चित करने के लिए SQL सर्वर में सबसे अच्छा तरीका है जब तक कि वे GREATEST या इन-लाइन MAX के लिए मूल समर्थन नहीं जोड़ते। इसे पोस्ट करने के लिए धन्यवाद - +1 आपको!
SqlRyan

10

अन्य उत्तर अच्छे हैं, लेकिन अगर आपको NULL मानों के बारे में चिंता करनी है, तो आप इस संस्करण को चाहते हैं:

SELECT o.OrderId, 
   CASE WHEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice) > ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
        THEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice)
        ELSE ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
   END
FROM Order o

1
एकमात्र आवश्यक ISSEULL ELSE के बाद है। प्रारंभिक ">" तुलना झूठी हो जाएगी और यदि कोई मान पहले से ही शून्य है, तो ELSE पर जाएगा।
फिल बी

10

एसक्यूएल सर्वर 2012 या अधिक है, तो आप के संयोजन का उपयोग कर सकते हैं IIFऔर ISNULL(या COALESCE2 मूल्यों की अधिकतम प्राप्त करने के लिए)।
जब उनमें से 1 भी NULL हो।

IIF(col1 >= col2, col1, ISNULL(col2, col1)) 

या यदि आप चाहते हैं कि जब दोनों NULL हो तो उसे 0 पर लौटना होगा

IIF(col1 >= col2, col1, COALESCE(col2, col1, 0)) 

उदाहरण स्निपेट:

-- use table variable for testing purposes
declare @Order table 
(
  OrderId int primary key identity(1,1),
  NegotiatedPrice decimal(10,2),
  SuggestedPrice decimal(10,2)
);

-- Sample data
insert into @Order (NegotiatedPrice, SuggestedPrice) values
(0, 1),
(2, 1),
(3, null),
(null, 4);

-- Query
SELECT 
     o.OrderId, o.NegotiatedPrice, o.SuggestedPrice, 
     IIF(o.NegotiatedPrice >= o.SuggestedPrice, o.NegotiatedPrice, ISNULL(o.SuggestedPrice, o.NegotiatedPrice)) AS MaxPrice
FROM @Order o

परिणाम:

OrderId NegotiatedPrice SuggestedPrice  MaxPrice
1       0,00            1,00            1,00
2       2,00            1,00            2,00
3       3,00            NULL            3,00
4       NULL            4,00            4,00

लेकिन अगर किसी को कई मानों की जरूरत है?
तब मैं घाटी के एकत्रीकरण के लिए आवेदन करने का सुझाव देता हूं।
इसका यह भी लाभ है कि यह एक ही समय में अन्य चीजों की गणना कर सकता है।

उदाहरण:

SELECT t.*
, ca.[Total]
, ca.[Maximum]
, ca.[Minimum]
, ca.[Average]
FROM SomeTable t
CROSS APPLY (
   SELECT 
    SUM(v.col) AS [Total], 
    MIN(v.col) AS [Minimum], 
    MAX(v.col) AS [Maximum], 
    AVG(v.col) AS [Average]
   FROM (VALUES (t.Col1), (t.Col2), (t.Col3), (t.Col4)) v(col)
) ca

8

उप क्वेरी बाहरी कॉलम से कॉलम तक पहुँच सकते हैं ताकि आप इस दृष्टिकोण का उपयोग MAXकॉलमों जैसे समुच्चय का उपयोग कर सकें । (संभवत: तब अधिक उपयोगी होगा जब इसमें अधिक संख्या में कॉलम शामिल हों)

;WITH [Order] AS
(
SELECT 1 AS OrderId, 100 AS NegotiatedPrice, 110 AS SuggestedPrice UNION ALL
SELECT 2 AS OrderId, 1000 AS NegotiatedPrice, 50 AS SuggestedPrice
)
SELECT
       o.OrderId, 
       (SELECT MAX(price)FROM 
           (SELECT o.NegotiatedPrice AS price 
            UNION ALL SELECT o.SuggestedPrice) d) 
        AS MaxPrice 
FROM  [Order]  o

अच्छा! यह बहुत अच्छी तरह से तराजू।
ग्रीनल्डमैन

2005 को अभी भी उन लोगों के लिए प्यार दिखाने के लिए। मुझे नहीं पता कि मैंने इस जवाब को कैसे अनदेखा किया। कवर्स के तहत, मुझे लगता है कि यह ठीक उसी तरह से प्रदर्शन करता है जैसा मैंने 2 साल बाद पोस्ट किया था। पूर्वव्यापी में, मुझे यह महसूस करना चाहिए और उस समय नए नए सिंटैक्स को शामिल करने के लिए आपके उत्तर को अपडेट करना चाहिए। क्षमा करें, काश मैं अब आपके साथ अपनी बातें साझा कर पाता।
माइक टिवेवी

@MikeTeeVee - धन्यवाद! हां कवर के तहत योजना समान होगी। लेकिन VALUESवाक्यविन्यास अच्छा है।
मार्टिन स्मिथ

6

SQL सर्वर 2012 पेश किया IIF:

SELECT 
    o.OrderId, 
    IIF( ISNULL( o.NegotiatedPrice, 0 ) > ISNULL( o.SuggestedPrice, 0 ),
         o.NegotiatedPrice, 
         o.SuggestedPrice 
    )
FROM 
    Order o

उपयोग करते समय NULLs को संभालने की सलाह दी जाती है IIF, क्योंकि NULLआपके दोनों तरफ (जैसा विरोध किया जाता है ) वापस करने boolean_expressionका कारण होगा ।IIFfalse_valueNULL


जब दूसरा मान नकारात्मक होगा, तो आपका समाधान पूरी तरह से नहीं चलेगा, यह अशक्त हो जाएगा
t-clausen.dk

5

मैं kcrumley द्वारा प्रदान किए गए समाधान के साथ जाऊंगा। NULLs को संभालने के लिए इसे थोड़ा संशोधित करें

create function dbo.HigherArgumentOrNull(@val1 int, @val2 int)
returns int
as
begin
  if @val1 >= @val2
    return @val1
  if @val1 < @val2
    return @val2

 return NULL
end

EDIT मार्क से टिप्पणी के बाद संशोधित । जैसा कि उन्होंने 3 वैल्यू लॉजिक x> NULL या x <NULL में सही बताया है, हमेशा NULL को वापस करना चाहिए। दूसरे शब्दों में अज्ञात परिणाम।


1
नल महत्वपूर्ण हैं। और उन्हें लगातार संभालना महत्वपूर्ण है। केवल NULL> x का उचित उत्तर NULL है।
मार्क ब्रैकेट

आप सही हैं, मैं अपने उत्तर को प्रतिबिंबित करने के लिए संशोधित करूंगा, यह इंगित करने के लिए धन्यवाद कि
kristof

यदि हम एक int और NULL पास करते हैं, तो मुझे लगता है कि गैर-शून्य मान लौटाए जाने के लिए यह अधिक सामान्य है, इसलिए फ़ंक्शन अधिकतम (x, y) और ISNULL (x, y) के संयोजन के रूप में कार्य कर रहा है। इसलिए मैं व्यक्तिगत रूप से अंतिम पंक्ति को बदलूंगा: वापसी ISNULL (@ val1, @ val2) - जो कि वास्तव में संभवतः है जो आपको :) से शुरू करना था
redcalx

@-लोकेटर, मार्क द्वारा टिप्पणी देखें
kristof

1
यह अविश्वसनीय रूप से धीमा होगा, क्योंकि सभी चीजें स्केलर यूडीएफ हैं। उपयोग इनलाइन UDFs बजाय
एके

4

इसके रूप में यह सरल है:

CREATE FUNCTION InlineMax
(
    @p1 sql_variant,
    @p2 sql_variant
)  RETURNS sql_variant
AS
BEGIN
    RETURN CASE 
        WHEN @p1 IS NULL AND @p2 IS NOT NULL THEN @p2 
        WHEN @p2 IS NULL AND @p1 IS NOT NULL THEN @p1
        WHEN @p1 > @p2 THEN @p1
        ELSE @p2 END
END;

पिछले उत्तर का चयन करें @ देखें टिप्पणी dbo.InlineMax (CAST (0.5 AS FLOAT), 100) गलत है।
लुका

4
SELECT o.OrderId,   
--MAX(o.NegotiatedPrice, o.SuggestedPrice)  
(SELECT MAX(v) FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) as ChoosenPrice  
FROM Order o

स्पष्टीकरण के लिए कृपया इस लेख से परामर्श करें: red-gate.com/simple-talk/sql/sql-training/…
टॉम आर्लेथ

2
कृपया अपने कोड में आवश्यक जानकारी को केवल एक लिंक द्वारा शामिल न करें। कल्पना करें कि यह लिंक एक दिन समाप्त हो जाएगा और आपका उत्तर तब बेकार हो जाएगा। तो कृपया आगे बढ़ें और सीधे अपने उत्तर में निबंधात्मक जानकारी जोड़ें। लेकिन आप अभी भी अन्य जानकारी को देखने के लिए दूसरों के लिए एक स्रोत के रूप में उस लिंक को प्रदान कर सकते हैं।
एल। गुथर्ड

3

उफ़, मैंने अभी-अभी इस सवाल का एक पोस्ट किया है ...

इसका उत्तर है, ओरेकल के सबसे बड़े जैसे फ़ंक्शन में कोई अंतर्निहित नहीं है , लेकिन आप यूडीएफ के साथ 2 कॉलम के लिए एक समान परिणाम प्राप्त कर सकते हैं, ध्यान दें, sql_variant का उपयोग यहां काफी महत्वपूर्ण है।

create table #t (a int, b int) 

insert #t
select 1,2 union all 
select 3,4 union all
select 5,2

-- option 1 - A case statement
select case when a > b then a else b end
from #t

-- option 2 - A union statement 
select a from #t where a >= b 
union all 
select b from #t where b > a 

-- option 3 - A udf
create function dbo.GREATEST
( 
    @a as sql_variant,
    @b as sql_variant
)
returns sql_variant
begin   
    declare @max sql_variant 
    if @a is null or @b is null return null
    if @b > @a return @b  
    return @a 
end


select dbo.GREATEST(a,b)
from #t

क्रिस्टोफ

इस उत्तर को पोस्ट करें:

create table #t (id int IDENTITY(1,1), a int, b int)
insert #t
select 1,2 union all
select 3,4 union all
select 5,2

select id, max(val)
from #t
    unpivot (val for col in (a, b)) as unpvt
group by id

1
ध्यान दें: GREATEST फ़ंक्शन कार्यान्वयन 2 पारमों के लिए ओरेकल व्यवहार से मेल खाएगा, यदि कोई भी परम शून्य है तो यह शून्य हो जाएगा
सैम केसर

2
Sql_variant का उपयोग करते समय आपको सावधान रहना चाहिए। आपका कार्य निम्न स्थिति में अप्रत्याशित परिणाम देगा: SELECT dbo.greatest (CAST (0.5 AS FLOAT), 100)
नील

@ नील सही है (मैंने इसे कठिन तरीका सीखा), आप इस प्रकार की समस्याओं को रोकने के लिए इस फ़ंक्शन को कैसे सुधारेंगे?
लुका

3

यहाँ एक उदाहरण है कि nulls को संभालना चाहिए और MSSQL के पुराने संस्करणों के साथ काम करना चाहिए। यह लोकप्रिय उदाहरणों में से एक में इनलाइन फ़ंक्शन पर आधारित है:

case
  when a >= b then a
  else isnull(b,a)
end

2

मैं शायद इसे इस तरह से नहीं करूंगा, क्योंकि यह पहले से ही उल्लेख किए गए CASE निर्माणों की तुलना में कम कुशल है - जब तक, शायद, आपने दोनों प्रश्नों के अनुक्रमित को कवर किया था। किसी भी तरह से, यह समान समस्याओं के लिए एक उपयोगी तकनीक है:

SELECT OrderId, MAX(Price) as Price FROM (
   SELECT o.OrderId, o.NegotiatedPrice as Price FROM Order o
   UNION ALL
   SELECT o.OrderId, o.SuggestedPrice as Price FROM Order o
) as A
GROUP BY OrderId

2

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

चयन करें 0.5 * ((@ val1 + @ val2) + ABS (@ val1 - @ val2))

में परिवर्तन

@ VAL1 * 0.5 + @ val2 * 0.5 + ABS (@ val1 * 0.5 - @ val2 * 0.5) का चयन करें

यदि आप कास्टिंग से बचना चाहते हैं तो कम से कम एक विकल्प।


2

यहाँ NULL हैंडलिंग (Xin के जवाब पर आधारित) के साथ एक IIF संस्करण है:

IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a > b, a, b))

तर्क इस प्रकार है, यदि दोनों में से कोई भी मान NULL है, तो जो NULL नहीं है उसे वापस करें (यदि दोनों NULL हैं, तो NULL वापस आ गया है)। अन्यथा अधिक से अधिक वापस कर दें।

MIN के लिए भी किया जा सकता है।

IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a < b, a, b))


1
SELECT o.OrderID
CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN
 o.NegotiatedPrice
ELSE
 o.SuggestedPrice
END AS Price

1
CREATE FUNCTION [dbo].[fnMax] (@p1 INT, @p2 INT)
RETURNS INT
AS BEGIN

    DECLARE @Result INT

    SET @p2 = COALESCE(@p2, @p1)

    SELECT
        @Result = (
                   SELECT
                    CASE WHEN @p1 > @p2 THEN @p1
                         ELSE @p2
                    END
                  )

    RETURN @Result

END

1

अपने सरलतम रूप में ...

CREATE FUNCTION fnGreatestInt (@Int1 int, @Int2 int )
RETURNS int
AS
BEGIN

    IF @Int1 >= ISNULL(@Int2,@Int1)
        RETURN @Int1
    ELSE
        RETURN @Int2

    RETURN NULL --Never Hit

END


1

यहाँ है @Scott Langham का जवाब सरल NULL हैंडलिंग के साथ:

SELECT
      o.OrderId,
      CASE WHEN (o.NegotiatedPrice > o.SuggestedPrice OR o.SuggestedPrice IS NULL) 
         THEN o.NegotiatedPrice 
         ELSE o.SuggestedPrice
      END As MaxPrice
FROM Order o


0
 -- Simple way without "functions" or "IF" or "CASE"
 -- Query to select maximum value
 SELECT o.OrderId
  ,(SELECT MAX(v)
   FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) AS MaxValue
  FROM Order o;

जबकि VALUESइनलाइन का दिलचस्प उपयोग , मुझे यकीन नहीं है कि यह CASEया की तुलना में सरल है IFF। मैं यह देखना चाहूंगा कि इस समाधान का प्रदर्शन अन्य विकल्पों के मुकाबले कैसे
रुकता है

0

शिन के जवाब पर विस्तार करना और तुलना मूल्य प्रकार मान लेना INT है, यह दृष्टिकोण भी काम करता है:

SELECT IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)

यह उदाहरण मानों के साथ एक पूर्ण परीक्षा है:

DECLARE @A AS INT
DECLARE @B AS INT

SELECT  @A = 2, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2

SELECT  @A = 2, @B = 3
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 3

SELECT  @A = 2, @B = NULL
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2    

SELECT  @A = NULL, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 1

0

MemSQL में निम्न कार्य करें:

-- DROP FUNCTION IF EXISTS InlineMax;
DELIMITER //
CREATE FUNCTION InlineMax(val1 INT, val2 INT) RETURNS INT AS
DECLARE
  val3 INT = 0;
BEGIN
 IF val1 > val2 THEN
   RETURN val1;
 ELSE
   RETURN val2;
 END IF; 
END //
DELIMITER ;

SELECT InlineMax(1,2) as test;

-1

प्रेस्टो में आप उपयोग कर सकते हैं

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