複数の列が同じCASE WHEN
条件を使用するSELECT
句を書き換えて条件を1回だけチェックする「より良い」方法はありますか?
以下の例を参照してください。
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
注意:
Oracle(実際にはSQL標準でも)では、CASE
は単一の値を返す式です。 notは、他の一部の言語と同様に、フローの制御に使用されます。したがって、複数の列やその他の操作を条件付きで決定するために使用することはできません。
より長いバージョンのコード(既に機能しているもの)をビューに配置し、正式なクエリではそれを心配しないでください。
より正規化された設計を検討することもできます。たとえば、キーの一部としてタイプを使用して、監査の詳細を別のテーブルに保存しませんか?これにより、特に型が追加されるので、コードの保守がはるかに容易になります...
これらのすべての列が同じテーブルからのものである場合は、次のようなものを使用できます。
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' ;