कई स्तंभों से न्यूनतम मूल्य का चयन करने का सबसे अच्छा तरीका क्या है?


82

SQL सर्वर 2005 में निम्न तालिका दी गई है:

ID   Col1   Col2   Col3
--   ----   ----   ----
1       3     34     76  
2      32    976     24
3       7    235      3
4     245      1    792

निम्नलिखित परिणाम प्राप्त करने वाले क्वेरी को लिखने का सबसे अच्छा तरीका क्या है (यानी कि अंतिम कॉलम की पैदावार - प्रत्येक पंक्ति के लिए Col1, Col2 और Col 3 से बाहर minium मान वाले स्तंभ )?

ID   Col1   Col2   Col3  TheMin
--   ----   ----   ----  ------
1       3     34     76       3
2      32    976     24      24
3       7    235      3       3
4     245      1    792       1

अपडेट करें:

स्पष्टीकरण के लिए (जैसा मैंने कॉमिक्स में कहा है) वास्तविक परिदृश्य में डेटाबेस ठीक से सामान्यीकृत है । ये "सरणी" कॉलम एक वास्तविक तालिका में नहीं हैं, लेकिन एक परिणाम सेट में हैं जो एक रिपोर्ट में आवश्यक है। और नई आवश्यकता यह है कि रिपोर्ट को इस MinValue कॉलम की भी आवश्यकता है। मैं अंतर्निहित परिणाम सेट को नहीं बदल सकता और इसलिए मैं एक आसान "जेल कार्ड से बाहर निकलना" के लिए टी-एसक्यूएल को देख रहा था।

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

वैसे भी, मैंने सोचा कि मैं अपने वर्तमान समाधान को पोस्ट करूंगा, जो मेरी बाधाओं को देखते हुए बहुत अच्छा काम करता है। यह UNPIVOT ऑपरेटर का उपयोग करता है:

with cte (ID, Col1, Col2, Col3)
as
(
    select ID, Col1, Col2, Col3
    from TestTable
)
select cte.ID, Col1, Col2, Col3, TheMin from cte
join
(
    select
        ID, min(Amount) as TheMin
    from 
        cte 
        UNPIVOT (Amount for AmountCol in (Col1, Col2, Col3)) as unpvt
    group by ID
) as minValues
on cte.ID = minValues.ID

मैं कहता हूँ कि मैं यह उम्मीद नहीं करता कि यह सर्वश्रेष्ठ प्रदर्शन की पेशकश करेगा, लेकिन परिस्थितियों को देखते हुए (मैं सभी प्रश्नों को नए MinValue कॉलम की आवश्यकता के लिए पुनः डिज़ाइन नहीं कर सकता), यह एक बहुत ही सुंदर है "जेल से बाहर निकलना कार्ड "।


11
IMHO लेखक का UNPIVOT समाधान अन्य उत्तरों से बेहतर है।
जो हैरिस

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

जवाबों:


59

इसे पूरा करने के कई तरीके होने की संभावना है। मेरा सुझाव केस / कब उपयोग करना है। 3 कॉलम के साथ, यह बहुत बुरा नहीं है।

Select Id,
       Case When Col1 < Col2 And Col1 < Col3 Then Col1
            When Col2 < Col1 And Col2 < Col3 Then Col2 
            Else Col3
            End As TheMin
From   YourTableNameHere

6
यह मेरा प्रारंभिक विचार था। लेकिन वास्तविक क्वेरी को 5 कॉलम की आवश्यकता होती है, और कॉलम की संख्या बढ़ सकती है। इसलिए CASE दृष्टिकोण थोड़ा सा लापरवाह हो जाता है। लेकिन यह काम करता है।
stucampbell

2
यदि स्तंभों की संख्या बढ़ सकती है, तो आप निश्चित रूप से इसे गलत कर रहे हैं - मेरी पोस्ट देखें (इस पर शेख़ी क्यों आपको अपना DB स्कीमा इस तरह सेट नहीं करना चाहिए :-)।
पाक्सिडाब्लो

2
धन्यवाद। जैसा कि मैंने एक अन्य टिप्पणी में उल्लेख किया है। मैं वास्तविक तालिकाओं को क्वेरी नहीं कर रहा हूँ। तालिकाओं को सही ढंग से सामान्य किया जाता है। यह क्वेरी विशेष रूप से जटिल क्वेरी का हिस्सा है और व्युत्पन्न तालिकाओं से मध्यवर्ती परिणामों पर काम कर रही है।
स्टिकैम्पबेल

2
उस मामले में, क्या आप उन्हें अलग तरह से प्राप्त कर सकते हैं ताकि वे सामान्य दिखें?
केव

3
@Gmastros से उत्तर पर एक ऐड जोड़ने के रूप में मैं इस मुद्दे पर भाग गया कि कुछ Cols में डेटा मिलान था इसलिए मुझे = साइन जोड़ना पड़ा। मेरे डेटा में अशक्त होने की क्षमता भी थी, इसलिए मुझे उस के लिए खाते में जोड़ना या बयान करना पड़ा। शायद ऐसा करने का एक आसान तरीका है लेकिन मुझे पिछले 6 महीनों में एक भी नहीं मिला है जिसे मैं देख रहा हूं। यहां शामिल सभी के लिए धन्यवाद। Id, CaseWhen (Col1 <= Col2 OR Col2 null) का चयन करें और (Col1 <= Col3 OR Col3 null है) फिर Col1 कब (Col2 <= Col1 OR Col1 null है) और (Col2 <= Col3 OR Col3 null है) फिर Col2 Else Col3 YourTableNameHere से TheMin के रूप में समाप्त
चाड पोर्टमैन

55

का उपयोग कर CROSS APPLY:

SELECT ID, Col1, Col2, Col3, MinValue
FROM YourTable
CROSS APPLY (SELECT MIN(d) AS MinValue FROM (VALUES (Col1), (Col2), (Col3)) AS a(d)) A

एसक्यूएल फिडल


दिलचस्प लगता है, लेकिन मैं यह काम करने के लिए नहीं मिल सकता है। क्या आप शायद थोड़ा स्पष्ट कर सकते हैं? thx
पैट्रिक होनोरेज़

2
@iDevlop मैंने अपने उत्तर में SQL फिडल डाला
निजाम

जिस चीज को मैं नहीं जानता था, वह थी स्केलर फंक्शन। ऐसा लगता है कि आपका जवाब भी बिना काम करता है cross apply। क्या यह मूल्य / प्रदर्शन को जोड़ता है? stackoverflow.com/a/14712024/78522
पैट्रिक होनोरेज़

@iDevlop यदि यह प्रदर्शन को वितरित नहीं करता है, तो यह पठनीयता को बढ़ाता है। उदाहरण के लिए, मैं कुछ ऐसा उपयोग कर सकता था where MinValue > 10, जिसे मैं बिना नहीं कर सकता थाCROSS APPLY
निजाम

2
वास्तव में, मुझे इस बीच "पुन: प्रयोज्य" लाभ को समझने का अवसर मिला। धन्यवाद। मैंने आज 2 चीजें सीखी ;-)
पैट्रिक होनोरेज़

31
SELECT ID, Col1, Col2, Col3, 
    (SELECT MIN(Col) FROM (VALUES (Col1), (Col2), (Col3)) AS X(Col)) AS TheMin
FROM Table

1
पकड़ने के लिए धन्यवाद। मुझे वह टैग याद आ गया। मैं वास्तव में नहीं जानता, और यह परीक्षण करने की क्षमता भी नहीं है। आगे जा रहे टैगों की जाँच में अधिक साहचर्य होगा।
dsz

3
अधिक सुरुचिपूर्ण समाधान नीचे हाथ करें - यह सुनिश्चित नहीं करें कि इसमें अधिक upvotes क्यों नहीं हैं।
jwolf

इनलाइन अधिकतम / मिनट के लिए यह अब तक का सबसे अच्छा तरीका है
सैक्समैन

अद्भुत समाधान।
फणी

16

MySQL पर, इसका उपयोग करें:

select least(col1, col2, col3) FROM yourtable

SQL कथन नहीं हो सकता है।
टीनो जोस थानिप्पारा 11

4
लेकिन कुछ मामलों में यह है। उन लोगों के लिए, यह एक अद्भुत जवाब है
किर्बी

1
8.1 के बाद से पोस्टग्रैस में उपलब्ध: Postgresql.org/docs/8.1/functions-conditional.html#AEN12704
स्वैबेल

1
यह गैर-मानक SQL एक्सटेंशन Microsoft SQL सर्वर को छोड़कर प्रत्येक डेटाबेस द्वारा बहुत अधिक समर्थित है।
मिकको रैंटलैनेन

LEASTMicrosoft SQL सर्वर प्रबंधित इंस्टेंसेस के नवीनतम संस्करण में काम करता है, ~ 12 दिन पहले। reddit.com/r/SQLServer/comments/k0dj2r/…
जॉन ज़ब्रोस्की

10

आप एक मोड़ के साथ "जानवर बल" दृष्टिकोण का उपयोग कर सकते हैं:

SELECT CASE
    WHEN Col1 <= Col2 AND Col1 <= Col3 THEN Col1
    WHEN                  Col2 <= Col3 THEN Col2
    ELSE                                    Col3
END AS [Min Value] FROM [Your Table]

जब पहली बार जब स्थिति विफल हो जाती है तो यह गारंटी देता है कि Col1 सबसे छोटा मूल्य नहीं है इसलिए आप इसे बाकी स्थितियों से समाप्त कर सकते हैं। इसी तरह बाद की स्थितियों के लिए। पांच कॉलम के लिए आपकी क्वेरी बन जाती है:

SELECT CASE
    WHEN Col1 <= Col2 AND Col1 <= Col3 AND Col1 <= Col4 AND Col1 <= Col5 THEN Col1
    WHEN                  Col2 <= Col3 AND Col2 <= Col4 AND Col2 <= Col5 THEN Col2
    WHEN                                   Col3 <= Col4 AND Col3 <= Col5 THEN Col3
    WHEN                                                    Col4 <= Col5 THEN Col4
    ELSE                                                                      Col5
END AS [Min Value] FROM [Your Table]

ध्यान दें कि यदि दो या अधिक स्तंभों के बीच एक टाई है, तो <=यह सुनिश्चित करता है कि हम CASEजल्द से जल्द बयान से बाहर निकलें ।


2
<=इसके बजाय का उपयोग करें , अन्यथा, पहले के बजाय अंतिम मिलान न्यूनतम मूल्य का उपयोग किया जाएगा।
Chezy525

6

यदि कॉलम आपके उदाहरण के अनुसार पूर्णांक थे, तो मैं एक फ़ंक्शन बनाऊंगा:

create function f_min_int(@a as int, @b as int) 
returns int
as
begin
    return case when @a < @b then @a else coalesce(@b,@a) end
end

फिर जब मुझे इसका उपयोग करने की आवश्यकता होगी तो मैं करूंगा:

select col1, col2, col3, dbo.f_min_int(dbo.f_min_int(col1,col2),col3)

यदि आपके पास 5 कॉलम्स हैं तो उपरोक्त बन जाता है

select col1, col2, col3, col4, col5,
dbo.f_min_int(dbo.f_min_int(dbo.f_min_int(dbo.f_min_int(col1,col2),col3),col4),col5)

4
MSSQL में अदिश कार्यों के हास्यास्पद खराब प्रदर्शन को देखते हुए मैं इस दृष्टिकोण के खिलाफ सलाह के लिए बाध्य महसूस कर रहा हूं। यदि आप इस सड़क पर जाते हैं तो कम से कम एक ऐसा फंक्शन लिखें जो एक ही बार में सभी 5 कॉलमों को पैरामीटर के रूप में ले ले। यह अभी भी खराब होने जा रहा है, लेकिन कम से कम थोड़ा बुरा = /
deroby

पुनरावृत्ति प्रदर्शन को कम करेगा। लेकिन यह आवश्यकता को पूरा करेगा।
टीनो जोस थानिप्पारा 11

6

ऐसा करने का सबसे अच्छा तरीका शायद यह करना नहीं है - यह अजीब है कि लोग अपने डेटा को इस तरह से संग्रहीत करने पर जोर देते हैं जिसमें सार्थक जानकारी निकालने के लिए SQL "जिम्नास्टिक" की आवश्यकता होती है, जब वांछित परिणाम प्राप्त करने के लिए बहुत आसान तरीके होते हैं यदि आप बस संरचना अपने स्कीमा थोड़ा बेहतर :-)

ऐसा करने का सही तरीका, मेरी राय में, निम्न तालिका है:

ID    Col    Val
--    ---    ---
 1      1      3
 1      2     34
 1      3     76

 2      1     32
 2      2    976
 2      3     24

 3      1      7
 3      2    235
 3      3      3

 4      1    245
 4      2      1
 4      3    792

साथ ID/Colप्राथमिक कुंजी के रूप (और संभवतः Colएक अतिरिक्त कुंजी के रूप में, अपनी आवश्यकताओं के आधार पर)। तब आपकी क्वेरी सरल हो जाती है select min(val) from tblऔर आप where col = 2अपने अन्य प्रश्नों का उपयोग करके अलग-अलग 'पुराने कॉलम' को अलग-अलग मान सकते हैं। यह भी आसान विस्तार के लिए अनुमति देता है 'पुराने स्तंभों' की संख्या बढ़नी चाहिए।

यह आपके प्रश्नों को इतना आसान बनाता है। मेरे द्वारा उपयोग की जाने वाली सामान्य दिशानिर्देश है, यदि आपके पास कभी ऐसा कुछ है जो डेटाबेस पंक्ति में एक सरणी की तरह दिखता है, तो आप शायद कुछ गलत कर रहे हैं और डेटा के पुनर्गठन के बारे में सोचना चाहिए।


हालाँकि, अगर किसी कारण से आप उन कॉलमों को नहीं बदल सकते हैं, तो मैं सुझाव देता हूँ कि सम्मिलित करें और ट्रिगर्स को अपडेट करें और एक और कॉलम जोड़ें जो इन ट्रिगर्स को न्यूनतम पर सेट करें Col1/2/3। यह ऑपरेशन की 'लागत' को चयन से अद्यतन / सम्मिलित करने के लिए दूर ले जाएगा जहां यह है - मेरे अनुभव में अधिकांश डेटाबेस तालिकाओं को पढ़ने की तुलना में कहीं अधिक बार पढ़ा जाता है इसलिए समय के साथ अधिक कुशल हो जाता है।

दूसरे शब्दों में, एक पंक्ति के लिए न्यूनतम केवल बदल जाता है जब अन्य स्तंभों में से एक बदल सकता है इसलिए कि की जब आप इसे हर बार जब आप का चयन करें (जो अगर डेटा नहीं बदल रहा है बर्बाद हो जाता है) की गणना की जानी चाहिए, नहीं। फिर आप एक तालिका के साथ समाप्त करेंगे:

ID   Col1   Col2   Col3   MinVal
--   ----   ----   ----   ------
 1      3     34     76        3
 2     32    976     24       24
 3      7    235      3        3
 4    245      1    792        1

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


18
उम। डायरिया के लिए धन्यवाद। असली डेटाबेस ठीक से सामान्यीकृत है। यह एक सरल उदाहरण था। वास्तविक क्वेरी जटिल है और जिन 5 स्तंभों में मेरी दिलचस्पी है, वे व्युत्पन्न तालिकाओं से मध्यवर्ती परिणाम हैं।
at को स्टुकैम्पबेल

3
डायट्रीब अभी भी दुर्भाग्य से खड़ा है। आपके द्वारा सुझाए गए फॉर्म की इंटरमीडिएट टेबल बनाना हर तरह की समस्याग्रस्त है जैसे कि स्थायी टेबल बनाना। यह इस तथ्य से स्पष्ट होता है कि आपको वह परिणाम प्राप्त करना है जो मैं आपको पसंद करने के लिए SQL जिम्नास्टिक को कॉल करना चाहता हूं।
paxdiablo

यदि एक पंक्ति में 'सरणी' की आवश्यकता के वास्तविक कारण हैं, तो हमें बेझिझक महसूस करें, लेकिन न्यूनतम मूल्य का चयन करने के लिए इसका उपयोग करना उनमें से एक नहीं है।
paxdiablo

2
मूल (यदि त्रुटिपूर्ण) तालिका संरचना को संरक्षित करने के लिए ट्रिगर सुझाव के लिए +1।
स्कॉट फर्ग्यूसन

1
क्या होगा यदि आप एक पदानुक्रम तालिका के साथ काम कर रहे हैं, तो यह स्वयं में शामिल हो गया?
नाथन ट्रेगिलस

5

आप इसे यूनियन क्वेरी के साथ भी कर सकते हैं। जैसे-जैसे स्तंभों की संख्या बढ़ती जाएगी, आपको क्वेरी को संशोधित करना होगा, लेकिन कम से कम यह एक सीधा आगे संशोधन होगा।

Select T.Id, T.Col1, T.Col2, T.Col3, A.TheMin
From   YourTable T
       Inner Join (
         Select A.Id, Min(A.Col1) As TheMin
         From   (
                Select Id, Col1
                From   YourTable

                Union All

                Select Id, Col2
                From   YourTable

                Union All

                Select Id, Col3
                From   YourTable
                ) As A
         Group By A.Id
       ) As A
       On T.Id = A.Id

2
यह काम करता है लेकिन जब पंक्ति की संख्या बढ़ जाती है तो प्रदर्शन कम हो जाएगा।
तोमलक

1
धन्यवाद। हाँ यह काम करता है। जैसा कि टोमलाक कहते हैं, मेरी वास्तविक क्वेरी में यह प्रदर्शन के लिए काफी बुरा होगा। लेकिन प्रयास के लिए +1। :)
स्टुकम्पबेल १५’०

4

यह क्रूर बल है लेकिन काम करता है

 select case when col1 <= col2 and col1 <= col3 then col1
           case when col2 <= col1 and col2 <= col3 then col2
           case when col3 <= col1 and col3 <= col2 then col3
    as 'TheMin'
           end

from Table T

... क्योंकि मिनट () केवल एक स्तंभ पर काम करता है और स्तंभों पर नहीं।


यह भी सबसे तेज़ होता है क्योंकि MIN निहित निहित नेस्ट लूप बनाता है।
जॉन ज़ब्रोस्की

2

यह प्रश्न और यह प्रश्न दोनों इसका उत्तर देने का प्रयास करते हैं।

रिकैप यह है कि ओरेकल में इसके लिए एक फ़ंक्शन है, जिसमें Sql सर्वर के साथ आप या तो उपयोगकर्ता-परिभाषित-फ़ंक्शन को परिभाषित करने या केस स्टेटमेंट का उपयोग करने से अटक जाते हैं।


2

कई कॉलम के लिए एक CASE स्टेटमेंट का उपयोग करना सबसे अच्छा है, हालांकि दो संख्यात्मक कॉलम i और j के लिए आप साधारण गणित का उपयोग कर सकते हैं:

min (i, j) = (i + j) / 2 - abs (ij) / 2

इस फॉर्मूले का उपयोग कई कॉलमों का न्यूनतम मूल्य प्राप्त करने के लिए किया जा सकता है लेकिन इसका वास्तव में गन्दा अतीत 2, मिनट (i, j, k) न्यूनतम होगा (i, min (j, k))


1

यदि आप एक संग्रहीत प्रक्रिया बनाने में सक्षम हैं, तो यह मानों की एक सरणी ले सकता है, और आप बस इसे कॉल कर सकते हैं।


ओरेकल में LEAST () नाम का एक फंक्शन है, जो वास्तव में आप चाहते हैं।
केव

रगड़ के लिए धन्यवाद :) कि मैं विश्वास नहीं कर सकता कि एसक्यूएल सर्वर एक समकक्ष नहीं है!
स्टिकैम्पबेल

मैं कहने जा रहा था, "अरे, मेरे पसंदीदा pgsql के पास भी नहीं है," लेकिन यह वास्तव में करता है। ;) फ़ंक्शन हालांकि लिखना मुश्किल नहीं होगा।
केव

ओह, सिवाय इसके कि टी-एसक्यूएल में सरणी समर्थन (???) भी नहीं है, मुझे लगता है कि आपके पास पांच-पैरामीटर फ़ंक्शन हो सकते हैं और यदि आपको और अधिक बस आवश्यकता है तो इसे
बढ़ाएं

1
select *,
case when column1 < columnl2 And column1 < column3 then column1
when columnl2 < column1 And columnl2 < column3 then columnl2
else column3
end As minValue
from   tbl_example

1
यह जी मास्ट्रोस के उत्तर का एक डुप्लिकेट है, इसलिए यदि आपको आश्चर्य होना चाहिए: मुझे लगता है कि नीचे-वोट कहां से आता है।
तोमलक १५’०

1

यूनियन क्वेरी पर थोड़ा ट्विस्ट:

DECLARE @Foo TABLE (ID INT, Col1 INT, Col2 INT, Col3 INT)

INSERT @Foo (ID, Col1, Col2, Col3)
VALUES
(1, 3, 34, 76),
(2, 32, 976, 24),
(3, 7, 235, 3),
(4, 245, 1, 792)

SELECT
    ID,
    Col1,
    Col2,
    Col3,
    (
        SELECT MIN(T.Col)
        FROM
        (
            SELECT Foo.Col1 AS Col UNION ALL
            SELECT Foo.Col2 AS Col UNION ALL
            SELECT Foo.Col3 AS Col 
        ) AS T
    ) AS TheMin
FROM
    @Foo AS Foo

1

यदि आप SQL 2005 का उपयोग करते हैं तो आप इस तरह से कुछ साफ कर सकते हैं:

;WITH    res
          AS ( SELECT   t.YourID ,
                        CAST(( SELECT   Col1 AS c01 ,
                                        Col2 AS c02 ,
                                        Col3 AS c03 ,
                                        Col4 AS c04 ,
                                        Col5 AS c05
                               FROM     YourTable AS cols
                               WHERE    YourID = t.YourID
                             FOR
                               XML AUTO ,
                                   ELEMENTS
                             ) AS XML) AS colslist
               FROM     YourTable AS t
             )
    SELECT  YourID ,
            colslist.query('for $c in //cols return min(data($c/*))').value('.',
                                            'real') AS YourMin ,
            colslist.query('for $c in //cols return avg(data($c/*))').value('.',
                                            'real') AS YourAvg ,
            colslist.query('for $c in //cols return max(data($c/*))').value('.',
                                            'real') AS YourMax
    FROM    res

इस तरह आप इतने सारे ऑपरेटरों में खो नहीं है :)

हालांकि, यह दूसरी पसंद से धीमी हो सकती है।

यह तुम्हारी पसंद है...


ठीक है, जैसा मैंने कहा, यह धीमा हो सकता है, लेकिन अगर आपके पास बहुत सारे कॉलम हैं (जाहिर है, वास्तव में खराब डीबी डिजाइन के परिणामस्वरूप!), यह इस (एवीजी के लिए कम से कम) का उपयोग करने के लायक हो सकता है। आप मुझे कोई संकेत नहीं देते अगर यह एक अच्छी पवित्र गाय या एक बुरा है :) हो सकता है कि आपको मुझे पता लगाने में मदद करने के लिए अप / डाउन वोट का उपयोग करना चाहिए।
leoinfo

यह वास्तव में अच्छा या बुरा नहीं था;)। मैं कोई डेटाबेस विशेषज्ञ नहीं हूं, इसलिए मैं सिर्फ "पवित्र गाय" कह रहा था क्योंकि सवाल ऐसा लग रहा था कि इसका एक तुच्छ उत्तर होगा। मुझे लगता है कि यह एक अच्छा एक है क्योंकि आप समस्या का एक लचीला, एक्स्टेंसिबल समाधान प्रदान करने में कामयाब रहे!
ड्रीमलैक्स

1

नीचे मैं कई तिथियों को प्राप्त करने के लिए एक अस्थायी तालिका का उपयोग करता हूं। पहले अस्थायी टेबल क्वेरीज़ में कई तारीखें (साथ ही क्वेरी के लिए अन्य मान) प्राप्त करने के लिए तालिकाओं को मिलाया गया था, दूसरा अस्थायी तालिका तब विभिन्न स्तंभों और न्यूनतम तिथि का उपयोग करती है, जिनमें कई तारीखें होती हैं।

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

--==================== this gets minimums and global min
if object_id('tempdb..#temp1') is not null
    drop table #temp1
if object_id('tempdb..#temp2') is not null
    drop table #temp2

select r.recordid ,  r.ReferenceNumber, i.InventionTitle, RecordDate, i.ReceivedDate
, min(fi.uploaddate) [Min File Upload], min(fi.CorrespondenceDate) [Min File Correspondence]
into #temp1
from record r 
join Invention i on i.inventionid = r.recordid
left join LnkRecordFile lrf on lrf.recordid = r.recordid
left join fileinformation fi on fi.fileid = lrf.fileid
where r.recorddate > '2015-05-26'
 group by  r.recordid, recorddate, i.ReceivedDate,
 r.ReferenceNumber, i.InventionTitle



select recordid, recorddate [min date]
into #temp2
from #temp1

update #temp2
set [min date] = ReceivedDate 
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
where t1.ReceivedDate < [min date] and  t1.ReceivedDate > '2001-01-01'

update #temp2 
set [min date] = t1.[Min File Upload]
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
where t1.[Min File Upload] < [min date] and  t1.[Min File Upload] > '2001-01-01'

update #temp2
set [min date] = t1.[Min File Correspondence]
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
where t1.[Min File Correspondence] < [min date] and t1.[Min File Correspondence] > '2001-01-01'


select t1.*, t2.[min date] [LOWEST DATE]
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
order by t1.recordid


0

यदि आप जानते हैं कि आप किन मूल्यों की तलाश कर रहे हैं, तो आमतौर पर एक स्थिति कोड, निम्नलिखित सहायक हो सकता है:

select case when 0 in (PAGE1STATUS ,PAGE2STATUS ,PAGE3STATUS,
PAGE4STATUS,PAGE5STATUS ,PAGE6STATUS) then 0 else 1 end
FROM CUSTOMERS_FORMS

0

मुझे पता है कि प्रश्न पुराना है, लेकिन मैं अभी भी उत्तर की आवश्यकता में था और अन्य उत्तरों से खुश नहीं था इसलिए मुझे अपना स्वयं का वशीकरण करना पड़ा जो कि @ paxdiablo´s उत्तर पर एक ट्विस्ट है ।


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

एनबी एक-आकार-फिट-सभी समाधान आगे नहीं!

CREATE TABLE #tempTable (ID int, columnName varchar(20), dataValue int)

INSERT INTO #tempTable 
  SELECT ID, 'Col1', Col1
    FROM sourceTable
   WHERE Col1 IS NOT NULL
INSERT INTO #tempTable 
  SELECT ID, 'Col2', Col2
    FROM sourceTable
   WHERE Col2 IS NOT NULL
INSERT INTO #tempTable 
  SELECT ID, 'Col3', Col3
    FROM sourceTable
   WHERE Col3 IS NOT NULL

SELECT ID
     , min(dataValue) AS 'Min'
     , max(dataValue) AS 'Max'
     , max(dataValue) - min(dataValue) AS 'Diff' 
  FROM #tempTable 
  GROUP BY ID

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

अतिरिक्त डेटा ( columnName, maxतों, ...) मेरी खोज में मेरी सहायता करने के लिए थे, इसलिए आपको उनकी आवश्यकता नहीं हो सकती है; मैं उन्हें यहाँ छोड़ दिया शायद कुछ विचारों को चिंगारी :-)।

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