2009-07-13 9 views
18

में बयान मैं एक क्वेरी है कि इस तरह से चलाने के लिए माना जाता रहा है -एसक्यूएल सर्वर 2008 - केस/तो चयन खण्ड

 

If(var = xyz) 
    SELECT col1, col2 
ELSE IF(var = zyx) 
    SELECT col2, col3 
ELSE 
    SELECT col7,col8 

FROM 

. 
. 
. 

मैं कैसे प्रत्येक खंड के लिए अलग-अलग क्वेरी लिखे बिना T-SQL में इस लक्ष्य को हासिल करते हैं? वर्तमान में मैं इसे

 

IF (var = xyz) { 
    Query1 
} 
ELSE IF (var = zyx) { 
    Query2 
} 
ELSE { 
    Query3 
} 

यह मूल्य के आधार पर अलग-अलग कॉलम चुनने के लिए बस बहुत ही अनावश्यक कोड है। कोई विकल्प?

उत्तर

18

बस यहां एक नोट है कि आप अनुकूलन के कारणों के लिए 3 अलग-अलग चयन होने से वास्तव में बेहतर हो सकते हैं। यदि आपके पास एक ही चयन है तो जेनरेटेड प्लान को सभी कॉलम कॉल 1, कोल् 2, कोलो 3, कोला 7, कॉल 8 इत्यादि को प्रोजेक्ट करना होगा, हालांकि, रनटाइम @ वीर के मूल्य के आधार पर, केवल कुछ की आवश्यकता है। इसका परिणाम ऐसी योजनाओं में हो सकता है जो अनावश्यक क्लस्टर्ड इंडेक्स लुकअप करते हैं क्योंकि गैर-क्लस्टर्ड इंडेक्स SELECT द्वारा अनुमानित सभी कॉलम को कवर नहीं करता है।

दूसरी तरफ 3 अलग-अलग चयन, प्रत्येक आवश्यक कॉलम को प्रोजेक्ट करने से प्रत्येक गैर-क्लस्टर इंडेक्स से लाभ हो सकता है जो प्रत्येक मामले में केवल आपके अनुमानित कॉलम को कवर करता है।

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

+3

+1 बहुत अच्छा अवलोकन –

22

आप मामले बयान

http://msdn.microsoft.com/en-us/library/ms181765.aspx

उदाहरण MSDN से नकल के लिए देख रहे हैं:

USE AdventureWorks; 
GO 
SELECT ProductNumber, Category = 
     CASE ProductLine 
     WHEN 'R' THEN 'Road' 
     WHEN 'M' THEN 'Mountain' 
     WHEN 'T' THEN 'Touring' 
     WHEN 'S' THEN 'Other sale items' 
     ELSE 'Not for sale' 
     END, 
    Name 
FROM Production.Product 
ORDER BY ProductNumber; 
GO 
+0

ऐसा लगता है कि मैं ninja'd कर रहे थे! :) –

+0

मैं अभी भी एक n00b हूँ इसलिए मैं (आसानी से) गलत हो सकता था, लेकिन मुझे लगता है कि यह वास्तव में सवाल का जवाब नहीं देता है, है ना? ओपी ने पूछा कि वह ** एकाधिक ** कॉलम का चयन कैसे कर सकता है, एक कॉलम के मानों के कई विकल्पों में से एक को असाइन नहीं करता है, जो ऐसा लगता है (और कई उत्तरों) कर रहे हैं। अगर मैं ओपी था, तो ऐसा लगता है कि @ जोएलमैनफोर्ड का जवाब सबसे सही है। यदि मैं हूं तो कृपया मुझे बताएं कि मैं गलत क्यों हूं! – dah97765

9
कुछ

प्रयास करें

तरह
SELECT 
    CASE var 
     WHEN xyz THEN col1 
     WHEN zyx THEN col2 
     ELSE col7 
    END AS col1, 
    ... 

दूसरे शब्दों में, एक सशर्त अभिव्यक्ति का उपयोग मान का चयन करने के लिए, फिर कॉलम का नाम बदलें।

वैकल्पिक रूप से, आप क्वेरी पूंछ को साझा करने के लिए कुछ प्रकार के गतिशील एसक्यूएल हैक का निर्माण कर सकते हैं; मैंने इसे पहले iBatis के साथ किया है।

0

केस उत्तर है, लेकिन आपको वापस आने वाले प्रत्येक कॉलम के लिए एक अलग केस स्टेटमेंट होना होगा। जब तक WHERE क्लॉज समान होता है, तब तक कई प्रश्नों में इसे अलग करने का अधिक लाभ नहीं होगा।

उदाहरण:

SELECT 
    CASE @var 
     WHEN 'xyz' THEN col1 
     WHEN 'zyx' THEN col2 
     ELSE col7 
    END, 
    CASE @var 
     WHEN 'xyz' THEN col2 
     WHEN 'zyx' THEN col3 
     ELSE col8 
    END 
FROM Table 
... 
0

सबसे स्पष्ट समाधान पहले से ही सूचीबद्ध हैं। जहां क्वेरी बैठी है (यानी आवेदन कोड में) आप हमेशा आईएफ स्टेटमेंट्स का उपयोग नहीं कर सकते हैं और इनलाइन केस स्टेटमेंट दर्दनाक हो सकते हैं जहां कई कॉलम सशर्त हो जाते हैं। मान लिया जाये कि Col1 + Col3 + Col7 एक ही प्रकार के हैं, और इसी तरह Col2, Col4 + Col8 आप यह कर सकते हैं:

SELECT Col1, Col2 FROM tbl WHERE @Var LIKE 'xyz' 
UNION ALL 
SELECT Col3, Col4 FROM tbl WHERE @Var LIKE 'zyx' 
UNION ALL 
SELECT Col7, Col8 FROM tbl WHERE @Var NOT LIKE 'xyz' AND @Var NOT LIKE 'zyx' 

इस के रूप में एक भी आदेश नहीं संबंध में कई प्रदर्शन लाभ कैशिंग योजना बनाने के लिए कर रहे हैं। इसके अलावा क्वेरी ऑप्टिमाइज़र उन बयानों को जल्दी से खत्म कर देगा जहां @Var स्टोरेज इंजन को छूए बिना उचित मूल्य से मेल नहीं खाता है।

2

सरल मामला अभिव्यक्ति:

CASE input_expression 
    WHEN when_expression THEN result_expression [ ...n ] 
    [ ELSE else_result_expression ] 
END 

खोजे गए मामले अभिव्यक्ति:

CASE 
    WHEN Boolean_expression THEN result_expression [ ...n ] 
    [ ELSE else_result_expression ] 
END 

संदर्भ: http://msdn.microsoft.com/en-us/library/ms181765.aspx

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