Birden Çok Sorgu Sütunu İçin Aynı DURUMDA KULLANILIR


12

Koşulların yalnızca bir kez kontrol edilmesi için SELECTbirden çok sütunun aynı CASE WHENkoşulları kullandığı bir cümleyi yeniden yazmanın "daha iyi" bir yolu var mı ?

Aşağıdaki örneğe bakın.

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

Sql olmayan psuedo kodunda, kod şöyle görünebilir:

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

Not:

  • Sorgu tarafından ima edilen bariz normalizasyon sorunlarının farkındayım. Sadece sorunu göstermek istedim.

Ve tüm bu sütunlar authTime, authUser, cmplTimeaynı tabloda mı?
ypercubeᵀᴹ

Yanıtlar:


7

Oracle'da bile (ve aslında SQL standardında), CASEtek bir değer döndüren bir ifadedir. O edilir değil bazı başka dillerde olduğu gibi akış kontrolü için kullandı. Bu nedenle, birden çok sütun veya diğer işlemler arasında koşullu olarak karar vermek için kullanılamaz.

Kodun daha uzun sürümünü (zaten çalışır) bir görünümde koyun ve resmi sorgularınızda endişelenmeyin.

Daha normalleştirilmiş bir tasarım da düşünebilirsiniz. Örneğin, denetleme ayrıntılarını neden anahtarın bir parçası olarak yazılan ayrı bir tabloda saklamıyorsunuz? Bu, özellikle daha fazla tür eklendiğinde kodunuzun bakımını çok daha kolay hale getirir ...


Even in Oracle... ancak Postgres'de bu kompozit tür genişletilerek mümkün.
Eugen Konkov

7

Tüm bu sütunlar aynı tablodansa, şöyle bir şey kullanabilirsiniz:

    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
Bunu yayınlamayı düşündüm, ama aynı uzun soluklu. Bunu yapmanın güzel bir yolu olduğunu sanmıyorum.
Philᵀᴹ

+1 sorusunu cevaplar, ancak diğerlerinin de belirttiği gibi, başladığınız şey daha iyidir. Ayrıca, her testStatus'a karşılık gelen değerleri birleştirebilir ve sonra bunları ayırabilirsiniz, ancak bu daha da kötü olacaktır.
Leigh Riffel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.