Uso dello stesso CASO QUANDO Condizioni per più colonne di query


12

Esiste un modo "migliore" per riscrivere una SELECTclausola in cui più colonne utilizzano le stesse CASE WHENcondizioni in modo che le condizioni vengano verificate una sola volta?

Vedi l'esempio sotto.

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

In psuedo-code non sql, il codice potrebbe apparire come:

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

Nota:

  • Sono a conoscenza degli ovvi problemi di normalizzazione implicati dalla query. Volevo solo dimostrare il problema.

E tutte queste colonne authTime, authUser, cmplTimesono nella stessa tabella?
ypercubeᵀᴹ

Risposte:


7

Anche in Oracle (e in effetti nello standard SQL), CASEè un'espressione che restituisce un singolo valore. E ' non utilizzato per il controllo del flusso come è in alcune altre lingue. Pertanto, non può essere utilizzato per decidere in modo condizionale tra più colonne o altre operazioni.

Direi di mettere la versione più lunga del codice (che già funziona) in una vista, e non ti preoccupare nelle tue domande formali.

Potresti anche prendere in considerazione un design più normalizzato. Ad esempio, perché non memorizzare i dettagli del controllo in una tabella separata, con il tipo come parte della chiave? Questo rende il tuo codice molto più facile da mantenere, specialmente quando vengono aggiunti più tipi ...


Even in Oracle... ma in Postgres ciò è possibile espandendo il tipo composito.
Eugen Konkov

7

Se tutte queste colonne provengono dalla stessa tabella, puoi usare qualcosa del genere:

    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
Ho pensato di postarlo, ma è altrettanto prolisso. Non penso che ci sia un bel modo di farlo.
Philᵀᴹ

Risponde alla domanda +1, ma come altri hanno indicato, è meglio iniziare. Potresti anche concatenare i valori che corrispondono a ciascun testStatus e poi dividerli, ma sarebbe anche peggio.
Leigh Riffel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.