Verwenden derselben CASE WHEN-Bedingungen für mehrere Abfragespalten


12

Gibt es eine "bessere" Möglichkeit, eine SELECTKlausel umzuschreiben , bei der mehrere Spalten dieselben CASE WHENBedingungen verwenden, sodass die Bedingungen nur einmal überprüft werden?

Siehe folgendes Beispiel.

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 Nicht-SQL-Pseudocode könnte der Code folgendermaßen aussehen:

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

Hinweis:

  • Mir sind die offensichtlichen Normalisierungsprobleme bekannt, die mit der Abfrage verbunden sind. Ich wollte das Problem nur demonstrieren.

Und all diese Spalten authTime, authUser, cmplTimesind in der gleichen Tabelle?
ypercubeᵀᴹ

Antworten:


7

Sogar in Oracle (und tatsächlich im SQL-Standard) CASEgibt ein Ausdruck einen einzelnen Wert zurück. Es wird nicht wie in anderen Sprachen zur Steuerung des Durchflusses verwendet. Daher kann es nicht verwendet werden, um eine bedingte Entscheidung zwischen mehreren Spalten oder anderen Vorgängen zu treffen.

Ich würde sagen, setzen Sie die längere Version des Codes (der bereits funktioniert) in eine Ansicht, und machen Sie sich darüber in Ihren formalen Abfragen keine Sorgen.

Sie können auch ein normaleres Design in Betracht ziehen. Warum speichern Sie beispielsweise die Überwachungsdetails nicht in einer separaten Tabelle, wobei Typ Teil des Schlüssels ist? Dies erleichtert die Pflege Ihres Codes erheblich, zumal weitere Typen hinzugefügt werden ...


7

Wenn alle diese Spalten aus derselben Tabelle stammen, können Sie Folgendes verwenden:

    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
Ich habe darüber nachgedacht, das zu posten, aber es ist genauso langwierig. Ich glaube nicht, dass es eine gute Möglichkeit gibt, das zu tun.
Philᵀᴹ

Es beantwortet die Frage +1, aber wie andere angegeben haben, ist es besser, mit was Sie begonnen haben. Sie können auch die Werte verketten, die den einzelnen testStatus entsprechen, und sie dann aufteilen. Dies wäre jedoch noch schlimmer.
Leigh Riffel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.