Apakah ada cara "lebih baik" untuk menulis ulang SELECT
klausa di mana beberapa kolom menggunakan CASE WHEN
kondisi yang sama sehingga kondisi hanya diperiksa satu kali?
Lihat contoh di bawah ini.
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
Dalam kode psuedo non-sql, kode tersebut mungkin terlihat seperti:
CASE testStatus
WHEN 'A'
StatusCol = 'Authorized'
lastEventTimeCol = authTime
lastEventUserCol = authUser
WHEN 'C'
StatusCol = 'Completed'
lastEventTimeCol = cmplTime
lastEventUserCol = cmplUser
...
END
catatan:
- Saya menyadari masalah normalisasi yang ditunjukkan oleh kueri. Saya hanya ingin menunjukkan masalahnya.
authTime
,authUser
,cmplTime
berada di meja yang sama?Jawaban:
Bahkan di Oracle (dan bahkan dalam standar SQL),
CASE
adalah ekspresi yang mengembalikan nilai tunggal. Itu tidak digunakan untuk kontrol aliran seperti di beberapa bahasa lain. Oleh karena itu, tidak dapat digunakan untuk memutuskan secara kondisional di antara beberapa kolom atau operasi lainnya.Saya akan mengatakan meletakkan versi kode yang lebih panjang (yang sudah berfungsi) dalam tampilan, dan jangan khawatir tentang hal itu dalam permintaan formal Anda.
Anda mungkin juga mempertimbangkan desain yang lebih normal. Misalnya mengapa tidak menyimpan dia mengaudit detail di tabel terpisah, dengan tipe sebagai bagian dari kunci? Ini membuat kode Anda lebih mudah dipelihara, terutama karena lebih banyak jenis ditambahkan ...
sumber
Even in Oracle
... tetapi dalam Postgres itu mungkin dengan memperluas tipe komposit.Jika semua kolom ini dari tabel yang sama, Anda dapat menggunakan sesuatu seperti ini:
sumber