Czy istnieje „lepszy” sposób przepisania SELECT
klauzuli, w której wiele kolumn używa tych samych CASE WHEN
warunków, aby warunki były sprawdzane tylko raz?
Zobacz przykład poniżej.
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
W kodzie psuedo innym niż SQL, kod może wyglądać następująco:
CASE testStatus
WHEN 'A'
StatusCol = 'Authorized'
lastEventTimeCol = authTime
lastEventUserCol = authUser
WHEN 'C'
StatusCol = 'Completed'
lastEventTimeCol = cmplTime
lastEventUserCol = cmplUser
...
END
Uwaga:
- Mam świadomość oczywistych problemów normalizacyjnych wynikających z zapytania. Chciałem tylko zademonstrować ten problem.
authTime
,authUser
,cmplTime
są w tej samej tabeli?Odpowiedzi:
Nawet w Oracle (a właściwie w standardzie SQL)
CASE
jest wyrażenie, które zwraca pojedynczą wartość. To jest nie używany do kontroli przepływu, jak to jest w innych językach. Dlatego nie można go używać do warunkowego decydowania o wielu kolumnach lub innych operacjach.Powiedziałbym, że umieść dłuższą wersję kodu (która już działa) w widoku i nie martw się o to w formalnych zapytaniach.
Możesz również rozważyć bardziej znormalizowany projekt. Na przykład, dlaczego nie przechowywać szczegółów audytu w osobnej tabeli, z typem jako częścią klucza? Dzięki temu kod jest znacznie łatwiejszy w utrzymaniu, szczególnie gdy dodaje się więcej typów ...
źródło
Even in Oracle
... ale w Postgres jest to możliwe poprzez rozwinięcie typu kompozytu.Jeśli wszystkie te kolumny pochodzą z tej samej tabeli, możesz użyć czegoś takiego:
źródło