2011-11-14 15 views
6

ओरेकल और माईएसक्यूएल में, मैं एक ऐसा फ़ंक्शन कैसे बना सकता हूं जो अनिश्चितकालीन पैरामीटर लेता है ताकि इसे GREATEST (value1, value2, ...) कहा जा सके?SQL उपयोगकर्ता परिभाषित कार्यों के लिए अनिश्चित संख्या में तर्क?

एक निश्चित मानक द्वारा दो मानों की तुलना करना काफी आसान है, लेकिन एक और तुलना में "अधिक" मान को पार करना मुझे लगता है कि मुझे SQL में काम नहीं लगता है।

धन्यवाद!

संपादित करें (माइक की टिप्पणी के बाद नीचे): मैं एकाधिक कॉलम की तुलना करने के लिए एक समाधान की तलाश में हूं। ठोस शब्दों में, मेरा सवाल है कि GREATEST() को यूडीएफ के रूप में कैसे कार्यान्वित किया जाए। निम्नलिखित कोड तीन कॉलम की तुलना करता है।

SELECT CASE WHEN CASE WHEN col_1 < col_2 THEN col_2 
       ELSE col_1 END < col_3 THEN col_3 
     ELSE CASE WHEN col_1 < col_2 THEN col_2 
       ELSE col_1 END END AS greatest 
    FROM figures; 

जाहिर है, यह इतना अच्छा नहीं है। यह एक सामान्य कार्य करने के लिए और अधिक उपयोगी होगा जो मूल्यों की सूची में एक ही तुलना विधि को लागू करता है।

तक एसक्यूएल मैं किसी भी SQL डेटाबेस उत्पाद मतलब है, लेकिन मैं एक समाधान है कि Oracle में काम करता है या MySQL

+0

इस रूप में एक ही है - चयन * से, x desc/asc द्वारा क्रम अधिकतम मूल्य पहले/आखिरी होना चाहिए? एक्सएसएलटी में भी, मैं बस चीजों को अधिकतम मूल्य प्राप्त करने के लिए सॉर्ट करता हूं? – Mike

+0

संभवतः आपका मतलब एसक्यूएल सर्वर - एसक्यूएल (आगे योग्यता के बिना) एक भाषा को संदर्भित करता है, जो विभिन्न विभिन्न उत्पादों द्वारा अलग-अलग डिग्री के लिए लागू होता है, और प्रत्येक के अपने अद्वितीय एक्सटेंशन भी होते हैं। –

+2

यहां एक तरीका है जो 'केस' कथन को बहुत बेहतर बनाता है। http://stackoverflow.com/questions/7995945/how-to-i-modify-this-t-sql-query-to-return-the-maximum-value-for-different-colum/7996068#7996068 –

उत्तर

2

Oracle (उदाहरणों कि unpivot समर्थन) में

SELECT MyID, MAX(GreatestVal) 
FROM figures 
    UNPIVOT (
      GreatestVal 
      FOR MyID 
      IN (col_1, col_2, col_3,...) 
     ); 

ओरेकल क्वेरी क्योंकि अपरीक्षित है पसंद करते हैं मेरे पास एक उदाहरण आसान नहीं है अनपिवोट पर अधिक जानकारी located here है और यह SQL सर्वर unpivot जैसी ही चीज है।

MySQL मैं कैसे MySQL में यह करने के लिए की अनिश्चित हूँ लेकिन एसक्यूएल सर्वर जवाब हैं के रूप में मैं अवसर की जांच कर सकते हैं

निम्नलिखित (जब तक कोई मुझे यह करने के लिए धड़कता है ;-)।):

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

SELECT dbo.GREATESTof3(col_1, col_2, col_3) 
FROM figures; 

CREATE FUNCTION GREATESTof3(@col_1 sql_variant = null, @col_2 sql_variant = null, @col_3 sql_variant = null) 
RETURNS sql_variant 
AS 
BEGIN 
    DECLARE @GreatestVal sql_variant 
    DECLARE @ColumnVals TABLE (Candidate sql_variant) 


    INSERT INTO @ColumnVals 
    SELECT @col_1 
    UNION ALL 
    SELECT @col_2 
    UNION ALL 
    SELECT @col_3 

    SELECT @GreatestVal = MAX(Candidate) 
    FROM @ColumnVals 

    RETURN @GreatestVal 
END 

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

विकल्प:

यह आपको पूरे मेज से तीन स्तंभों की अधिकतम मूल्य देता है और स्तंभों की एक गतिशील संख्या है आसान होगा:

SELECT MAX([Value]) AS Greatest 
FROM figures 
UNPIVOT 
(
    [Value] 
    FOR ColumnName IN ([Col_1], [Col_2], [Col_3]) 
) AS unpvt 

मान लिया जाये कि आप कुछ rowid है या आउटपुट में आप चाहते हैं कि एक और कॉलम ताकि आप प्रत्येक पंक्ति के लिए निर्दिष्ट कॉलम से सबसे बड़ा प्राप्त कर सकें:

SELECT RowID, MAX([Value]) AS Greatest 
FROM figures 
UNPIVOT 
(
    [Value] 
    FOR ColumnName IN ([Col_1], [Col_2], [Col_3]) 
) AS unpvt 
GROUP BY RowID 
0

एक और SQL सर्वर विकल्प (यह सुनिश्चित नहीं है कि यह MySQL/Oracle में कितना अच्छा अनुवाद करेगा)।

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

CREATE Function [dbo].[GreatestFromList] 
(@ListOfValues VARCHAR(8000)) 

RETURNS INT 

AS 

BEGIN 

DECLARE @ListOfValuesTable TABLE (ValueColumn INT) 

    DECLARE @spot1 SMALLINT, @str1 VARCHAR(8000) 

    WHILE @ListOfValues <> '' 
    BEGIN 
     SET @spot1 = CHARINDEX(',', @ListOfValues) 
     IF @spot1>0 
      BEGIN 
       SET @str1 = LEFT(@ListOfValues, @spot1-1) 
       SET @ListOfValues = RIGHT(@ListOfValues, LEN(@ListOfValues)[email protected]) 
      END 
     ELSE 
      BEGIN 
       SET @str1 = @ListOfValues 
       SET @ListOfValues = '' 
      END 
     INSERT INTO @ListOfValuesTable (ValueColumn) VALUES(convert(int, @str1)) 
    END 

DECLARE @GreatestValue INT 

SELECT @GreatestValue = SELECT MAX(ValueColumn) FROM @ListOfValuesTable 

RETURN @GreatestValue 

END 
संबंधित मुद्दे