2011-12-02 19 views
21

मैं जैसे, मेरे मामले बयान में एक से अधिक मान वापस जाने के लिए करना चाहते हैं:केस स्टेटमेंट, एकाधिक चर कैसे वापस करें?

SELECT 
    CASE 
    WHEN <condition 1> THEN <value1=a1, value2=b1> 
    WHEN <condition 2> THEN <value1=a2, value2=b2> 
    ELSE <value1=a3, value3=b3> 
    END 
FROM <table> 

बेशक मैं मामले हालत कई बार एक मूल्य लिखते हैं, हर बार वापसी कर सकते हैं। हालांकि, जैसा कि मेरे पास कई स्थितियों को फिट करने की आवश्यकता है, 100 कहें। बार-बार केस की स्थिति दोहराना अच्छा नहीं है।

एक और सवाल मैं पूछना चाहूँगा, जो एक रिकॉर्ड फिट एकाधिक हालत अगर happend? क्या इसका मतलब यह है कि यह उन सभी को वापस कर देगा या सिर्फ अंतिम? जैसे हालत 1 स्थिति का सबसेट बन सकता है 2. क्या होगा?

+0

क्या यह एमएस एसक्यूएल सर्वर है? – MatBailie

+0

हाँ, यह ...... – yzhang

+0

क्या आप अपने परिदृश्य को स्पष्ट कर सकते हैं? उदाहरण के लिए, 100 अलग-अलग केस स्थितियों में से प्रत्येक मान 1 और मान 2 के लिए 100 अलग-अलग लागू मानों का कारण बनता है, या 100 अलग-अलग स्थितियों में से कई एक ही परिणाम उत्पन्न करेंगे? क्या हालात अलग-अलग क्षेत्रों के सभी संयोजनों के संयोजन हैं, या वे एक ही क्षेत्र के अलग-अलग संभावित मूल्य हैं? –

उत्तर

13

बुनियादी तरीका, दुर्भाग्य से, अपने आप को दोहराने के लिए है।

SELECT 
    CASE WHEN <condition 1> THEN <a1> WHEN <condition 2> THEN <a2> ELSE <a3> END, 
    CASE WHEN <condition 1> THEN <b1> WHEN <condition 2> THEN <b2> ELSE <b3> END 
FROM 
    <table> 

सौभाग्य से, सबसे आरडीबीएमएस पर्याप्त चतुर की स्थिति कई बार का मूल्यांकन करने की जरूरत नहीं कर रहे हैं। यह सिर्फ अनावश्यक टाइपिंग है।


एमएस एसक्यूएल सर्वर में (2005+) आप संभावित उपयोग क्रॉस इस के लिए एक विकल्प के रूप में लागू हो सकते हैं। हालांकि मुझे पता नहीं कैसे performant यह है ... है

SELECT 
    * 
FROM 
    <table> 
CROSS APPLY 
    (
    SELECT a1, b1 WHERE <condition 1> 
    UNION ALL 
    SELECT a2, b2 WHERE <condition 2> 
    UNION ALL 
    SELECT a3, b3 WHERE <condition 3> 
) 
    AS case_proxy 

यहां उल्लेखनीय नकारात्मक पक्ष यह कोई और नहीं के बराबर है कि वहाँ और कहा कि केवल इस तरह के तैयार किए जा करने के लिए के रूप में सभी की स्थिति सकता सब वापसी मान, वे की जरूरत है एक समय में कभी भी सच हो सकता है।


संपादित

तो नीरस के जवाब बल्कि दृष्टिकोण शामिल हों की तुलना में एक संघ के लिए बदल गया है, यह बहुत ही इस के समान हो जाता है। हालांकि, मुख्य अंतर यह है कि यह केवल एक बार प्रति शर्त (आपके मामले में 100 गुना) की बजाय एक बार इनपुट डेटा सेट स्कैन करता है।


संपादित

मैं भी पाया है कि आपने मतलब हो सकता है कि मूल्यों मामला बयानों द्वारा दिया निर्धारित हैं। एक ही शर्त से मेल खाने वाले सभी रिकॉर्ड सटीक नाम मान मान 1 और मान 2 में प्राप्त करते हैं। यह इस तरह बनाया जा सकता है ...

WITH 
    checked_data AS 
(
    SELECT 
    CASE WHEN <condition1> THEN 1 
     WHEN <condition2> THEN 2 
     WHEN <condition3> THEN 3 
     ... 
     ELSE     100 
    END AS condition_id, 
    * 
    FROM 
    <table> 
) 
, 
    results (condition_id, value1, value2) AS 
(
    SELECT 1, a1, b1 
    UNION ALL 
    SELECT 2, a2, b2 
    UNION ALL 
    SELECT 3, a3, b3 
    UNION ALL 
    ... 
    SELECT 100, a100, b100 
) 
SELECT 
    * 
FROM 
    checked_data 
INNER JOIN 
    results 
    ON results.condition_id = checked_data.condition_id 
6

एक CASE बयान केवल एक मान लौट सकते हैं।

आप इसे एक सबक्वायरी में बदल सकते हैं और फिर JOIN जो भी आप अन्य संबंधों के साथ काम कर रहे हैं। उदाहरण के लिए (का उपयोग कर एसक्यूएल सर्वर 2K5 + सीटीई):

WITH C1 AS (
    SELECT a1 AS value1, b1 AS value2 
    FROM table 
    WHERE condition1 
), C2 AS (
    SELECT a2 AS value1, b2 AS value2 
    FROM table 
    WHERE condition2 
), C3 AS (
    SELECT a3 AS value1, b3 AS value2 
    FROM table 
    WHERE condition3 
) 
SELECT value1, value2 
FROM -- some table, joining C1, C2, C3 CTEs to get the cased values 
; 
+0

शामिल होने के बजाय (संभवतः सहकर्मी बयानों के साथ बाहरी जुड़ता है), शायद आप इन दोनों को एक साथ जोड़ना चाहते हैं। धारणा के साथ कि किसी दिए गए इनपुट रिकॉर्ड के लिए केवल एक शर्त ही सच है। फिर भी, इसमें प्रत्येक शर्त के लिए एक बार स्रोत डेटा सेट स्कैनिंग शामिल होगा, और इसलिए डेटा के 100 स्कैन होंगे। – MatBailie

+0

@Dems: हाँ, यह भी काम करेगा। ओपी प्रश्न में 'ELSE' स्थिति 'ELSE ' लिखा गया है, इसलिए कॉलम सभी समान नहीं हैं। मैंने अपने जवाब में "तय" किया है, लेकिन यह एक टाइपो नहीं हो सकता है। – Yuck

+0

अच्छी जगह, मैं * एक टाइपो * मानता हूं, यह रिलीज़ हो सकता है, और इसलिए अन्य परिणामों के लिए मूल्य 2 में NULL की आवश्यकता होती है। – MatBailie

5

CASE परिभाषा से केवल एक ही मान देता है। कभी।

यह भी (लगभग हमेशा) शॉर्ट सर्किट, यदि आपका पहला स्थिति उत्पन्न होने पर कोई अन्य चेक के चलाए जा रहे हैं, जिसका मतलब है।

+0

+1 क्या ऐसी कोई स्थितियां हैं जहां यह * शॉर्ट-सर्किट नहीं है? –

+0

@ मार्कबैनिस्टर - हाँ लेकिन वे छोटी हैं (SQL सर्वर में)। मूल रूप से मैंने देखा है कि एकमात्र परिस्थिति है जहां आप एक चर के कुल के साथ तुलना करते हैं ('CASE जब MAX (@var) ... ')। यह उन सभी का मूल्यांकन करेगा लेकिन फिर भी सही मूल्य वापस कर देगा। – JNK

0

आप एक subselect एक संघ के साथ संयुक्त इस्तेमाल कर सकते हैं। जब भी आप इस उदाहरण में एक से अधिक शर्त इस्तेमाल के लिए या कोष्ठक के साथ एक ही क्षेत्रों लौट सकते हैं:

SELECT * FROM 
    (SELECT val1, val2 FROM table1 WHERE (condition1 is true) 
            OR (condition2 is true)) 
UNION 
SELECT * FROM 
    (SELECT val5, val6 FROM table7 WHERE (condition9 is true) 
            OR (condition4 is true)) 
+0

और अन्य 99 स्थितियों के लिए? (यह 2 फ़ील्ड देता है, लेकिन केवल 1 शर्त के लिए) – MatBailie

+0

यूनियन का उपयोग करें, प्रति शर्त एक सबक्वायरी। –

+0

@Dems: इसके अलावा आप यहां 'OR' का उपयोग कर सकते हैं, (मैं इसे फिट करने के लिए अपना उदाहरण संपादित करता हूं) –

0

किसी SQL मामला खंड में, पहली सफलतापूर्वक मिलान किया हालत लागू किया जाता है और बाद में किसी भी मिलान की स्थिति अनदेखी कर रहे हैं ।

2

अपने मामले में आप दो मामले staements, आप वापस आ चाहते प्रत्येक मान के लिए एक का प्रयोग करेंगे।

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