Есть ли «лучший» способ переписать SELECT
предложение, когда несколько столбцов используют одинаковые CASE WHEN
условия, чтобы условия проверялись только один раз?
Смотрите пример ниже.
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
В не SQL-псевдо-коде код может выглядеть следующим образом:
CASE testStatus
WHEN 'A'
StatusCol = 'Authorized'
lastEventTimeCol = authTime
lastEventUserCol = authUser
WHEN 'C'
StatusCol = 'Completed'
lastEventTimeCol = cmplTime
lastEventUserCol = cmplUser
...
END
Замечания:
- Я знаю об очевидных проблемах нормализации, подразумеваемых запросом. Я только хотел продемонстрировать проблему.
authTime
,authUser
,cmplTime
находятся в одной и той же таблицы?Ответы:
Даже в Oracle (и фактически в стандарте SQL)
CASE
есть выражение, которое возвращает одно значение. Он не используется для управления потоком, как в некоторых других языках. Следовательно, его нельзя использовать для условного выбора между несколькими столбцами или другими операциями.Я бы сказал, поместите более длинную версию кода (которая уже работает) в представление, и не беспокойтесь об этом в ваших официальных запросах.
Вы могли бы также рассмотреть более нормализованный дизайн. Например, почему бы не хранить данные аудита в отдельной таблице с типом как частью ключа? Это значительно упрощает поддержку вашего кода, особенно когда добавляется больше типов ...
источник
Even in Oracle
... но в Postgres это возможно путем расширения составного типа.Если все эти столбцы из одной таблицы, вы можете использовать что-то вроде этого:
источник