एकाधिक क्वेरी कॉलम के लिए एक ही मामले का उपयोग करते हुए


12

क्या एक SELECTखंड को फिर से लिखने का एक "बेहतर" तरीका है जहां कई कॉलम समान CASE WHENशर्तों का उपयोग करते हैं ताकि शर्तों को केवल एक बार जांचा जाए?

नीचे दिए गए उदाहरण देखें।

SELECT
    CASE testStatus 
        WHEN 'A' THEN 'Authorized'
        WHEN 'C' THEN 'Completed'
        WHEN 'P' THEN 'In Progress'
        WHEN 'X' THEN 'Cancelled'
    END AS Status,

    CASE testStatus 
        WHEN 'A' THEN authTime
        WHEN 'C' THEN cmplTime
        WHEN 'P' THEN strtTime
        WHEN 'X' THEN cancTime
    END AS lastEventTime,

    CASE testStatus 
        WHEN 'A' THEN authBy
        WHEN 'C' THEN cmplBy
        WHEN 'P' THEN strtBy
        WHEN 'X' THEN cancBy
    END AS lastEventUser
FROM test

गैर-वर्गीय psuedo- कोड में, कोड की तरह लग सकता है:

CASE testStatus
    WHEN 'A'
        StatusCol        = 'Authorized'
        lastEventTimeCol = authTime 
        lastEventUserCol = authUser
    WHEN 'C'
        StatusCol        = 'Completed'
        lastEventTimeCol = cmplTime
        lastEventUserCol = cmplUser
    ...
END

ध्यान दें:

  • मैं क्वेरी द्वारा निहित स्पष्ट सामान्यीकरण मुद्दों से अवगत हूं। मैं केवल इस मुद्दे को प्रदर्शित करना चाहता था।

और इन सभी स्तंभों authTime, authUser, cmplTimeएक ही तालिका में कर रहे हैं?
ypercube y

जवाबों:


7

ओरेकल में भी (और वास्तव में एसक्यूएल मानक में), CASEएक अभिव्यक्ति है जो एकल मान लौटाता है। इसका उपयोग प्रवाह के नियंत्रण के लिए नहीं किया जाता है, जैसा कि कुछ अन्य भाषाओं में है। इसलिए, इसका उपयोग कई कॉलम या अन्य कार्यों के बीच सशर्त रूप से तय करने के लिए नहीं किया जा सकता है।

मैं कहूंगा कि कोड का लंबा संस्करण (जो पहले से ही काम करता है) एक दृश्य में, और अपने औपचारिक प्रश्नों में इसके बारे में चिंता न करें।

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


Even in Oracle... लेकिन पोस्टग्रैज में जो समग्र प्रकार का विस्तार करके संभव है।
यूजेन कोनकोव

7

यदि ये सभी कॉलम एक ही तालिका से हैं, तो आप कुछ इस तरह का उपयोग कर सकते हैं:

    SELECT  
        'Authorized' AS StatusCol,
        authTime     AS lastEventTimeCol, 
        authUser     AS lastEventUserCol 
    FROM test
    WHERE testStatus = 'A'

  UNION ALL

    SELECT  
        'Completed', 
        cmplTime,
        cmplUser    
    FROM test
    WHERE testStatus = 'C'

  UNION ALL

    SELECT  
        'In Progress', 
        strtTime,
        strtUser    
    FROM test
    WHERE testStatus = 'P'

  UNION ALL

    SELECT  
        'Cancelled', 
        cancTime,
        cancUser    
    FROM test
    WHERE testStatus = 'X' ;

2
मैंने पोस्ट करते हुए कहा, लेकिन यह केवल लंबे समय से प्रसारित है। मुझे नहीं लगता कि ऐसा करने का एक अच्छा तरीका है।
फिलो

यह प्रश्न +1 का उत्तर देता है, लेकिन जैसा कि दूसरों ने संकेत दिया है कि आपने जो शुरू किया है वह बेहतर है। आप उन मानों को भी अलग कर सकते हैं जो प्रत्येक टेस्टस्टैटस के अनुरूप हैं और फिर उन्हें अलग कर सकते हैं, लेकिन यह और भी बुरा होगा।
लेह रिफ़ेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.