Gibt es eine "bessere" Möglichkeit, eine SELECT
-Klausel neu zu schreiben, bei der mehrere Spalten dieselben CASE WHEN
- Bedingungen verwenden, sodass die Bedingungen nur einmal überprüft werden?
Siehe das folgende 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:
Selbst in Oracle (und tatsächlich im SQL-Standard) ist CASE
ein Ausdruck, der einen einzelnen Wert zurückgibt. Es wird nicht zur Steuerung des Flusses verwendet, wie es in einigen anderen Sprachen der Fall ist. Daher kann es nicht verwendet werden, um bedingt zwischen mehreren Spalten oder anderen Operationen zu entscheiden.
Ich würde sagen, stellen Sie die längere Version des Codes (die bereits funktioniert) in eine Ansicht und sorgen Sie sich in Ihren formalen Abfragen nicht darum.
Sie könnten auch ein normaleres Design in Betracht ziehen. Warum speichern Sie beispielsweise die Überwachungsdetails nicht in einer separaten Tabelle mit dem Typ als Teil des Schlüssels? Dies erleichtert die Wartung Ihres Codes erheblich, insbesondere wenn weitere Typen hinzugefügt werden ...
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' ;