Existe-t-il une "meilleure" façon de réécrire une clause SELECT
où plusieurs colonnes utilisent la même CASE WHEN
conditions pour que les conditions ne soient vérifiées qu'une seule fois?
Voir l'exemple ci-dessous.
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
En code pseudo non SQL, le code pourrait ressembler à:
CASE testStatus
WHEN 'A'
StatusCol = 'Authorized'
lastEventTimeCol = authTime
lastEventUserCol = authUser
WHEN 'C'
StatusCol = 'Completed'
lastEventTimeCol = cmplTime
lastEventUserCol = cmplUser
...
END
Remarque:
Même dans Oracle (et en fait dans le standard SQL), CASE
est une expression qui renvoie une seule valeur. Il est pas utilisé pour contrôler le flux comme il l'est dans certaines autres langues. Par conséquent, il ne peut pas être utilisé pour décider conditionnellement entre plusieurs colonnes ou d'autres opérations.
Je dirais de mettre la version plus longue du code (qui fonctionne déjà) dans une vue, et ne vous inquiétez pas à ce sujet dans vos requêtes formelles.
Vous pouvez également envisager une conception plus normalisée. Par exemple, pourquoi ne pas stocker les détails de l'audit dans une table séparée, avec le type dans la clé? Cela rend votre code beaucoup plus facile à maintenir, d'autant plus que davantage de types sont ajoutés ...
Si toutes ces colonnes proviennent de la même table, vous pouvez utiliser quelque chose comme ceci:
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' ;