Ok saya memiliki tabel dengan kunci yang diindeks dan bidang yang tidak diindeks. Saya perlu menemukan semua record dengan nilai tertentu dan mengembalikan barisnya. Saya ingin tahu apakah saya dapat memesan dengan beberapa nilai.
Contoh:
id x_field
-- -----
123 a
124 a
125 a
126 b
127 f
128 b
129 a
130 x
131 x
132 b
133 p
134 p
135 i
semu: ingin hasil diurutkan seperti ini, where ORDER BY x_field = 'f', 'p', 'i', 'a'
SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', 'a'
Jadi hasilnya adalah:
id x_field
-- -----
127 f
133 p
134 p
135 i
123 a
124 a
125 a
129 a
Sintaksnya valid tetapi ketika saya menjalankan kueri, ia tidak pernah mengembalikan hasil apa pun, bahkan jika saya membatasinya menjadi 1 catatan. Apakah ada cara lain untuk melakukannya?
Pikirkan x_field sebagai hasil tes dan saya perlu memvalidasi semua catatan yang termasuk dalam kondisi tersebut. Saya ingin memesan hasil tes dengan nilai gagal, nilai lulus. Jadi saya bisa memvalidasi nilai yang gagal terlebih dahulu dan kemudian nilai yang diteruskan menggunakan ORDER BY.
Yang tidak bisa saya lakukan:
- GROUP BY, karena saya perlu mengembalikan nilai record tertentu
- DI MANA x_field IN ('f', 'p', 'i', 'a'), saya memerlukan semua nilai karena saya mencoba menggunakan satu kueri untuk beberapa uji validasi. Dan nilai x_field tidak dalam urutan DESC / ASC
Setelah menulis pertanyaan ini saya mulai berpikir bahwa saya perlu memikirkan kembali ini, LOL!
sumber
Jawaban:
... WHERE x_field IN ('f', 'p', 'i', 'a') ... ORDER BY CASE x_field WHEN 'f' THEN 1 WHEN 'p' THEN 2 WHEN 'i' THEN 3 WHEN 'a' THEN 4 ELSE 5 --needed only is no IN clause above. eg when = 'b' END, id
sumber
Anda dapat menggunakan LEFT JOIN dengan "VALUES ('f', 1), ('p', 2), ('a', 3), ('i', 4)" dan menggunakan kolom kedua dalam urutan Anda -dengan ekspresi. Postgres akan menggunakan Hash Join yang akan jauh lebih cepat daripada CASE besar jika Anda memiliki banyak nilai. Dan lebih mudah untuk membuat otomatis.
Jika informasi pemesanan ini diperbaiki, maka itu harus memiliki tabelnya sendiri.
sumber
Mencoba:
Anda berada di jalur yang benar, tetapi dengan meletakkan x_field hanya pada nilai F, 3 lainnya diperlakukan sebagai konstanta dan tidak dibandingkan dengan apa pun dalam kumpulan data.
sumber
Gunakan
case
sakelar untuk menerjemahkan kode menjadi angka yang dapat diurutkan:ORDER BY case x_field when 'f' then 1 when 'p' then 2 when 'i' then 3 when 'a' then 4 else 5 end
sumber
Saya menemukan solusi yang jauh lebih bersih untuk ini:
Catatan: array_position membutuhkan Postgres v9.5 atau lebih tinggi.
sumber
array_position(ARRAY[1, 0]::integer[], x_field)
The
CASE
danORDER BY
saran semua harus bekerja, tapi aku akan menyarankan kuda warna yang berbeda. Dengan asumsi bahwa hanya ada sejumlah nilai yang masuk akalx_field
dan Anda sudah tahu apa itu, buat tipe enumerasi dengan F, P, A, dan I sebagai nilai (ditambah nilai lain yang mungkin berlaku). Enums akan mengurutkan dalam urutan yang tersirat olehCREATE
pernyataan mereka . Selain itu, Anda dapat menggunakan nama nilai yang berarti — aplikasi Anda yang sebenarnya mungkin melakukannya dan Anda baru saja menutupinya untuk kerahasiaan — tanpa membuang ruang, karena hanya posisi ordinal yang disimpan.sumber
Anda dapat mengurutkan berdasarkan kolom yang dipilih atau ekspresi lain.
Berikut contoh cara memesan berdasarkan hasil pernyataan kasus:
SELECT col1 , col2 FROM tbl_Bill WHERE col1 = 0 ORDER BY -- order by case-statement CASE WHEN tbl_Bill.IsGen = 0 THEN 0 WHEN tbl_Bill.IsGen = 1 THEN 1 ELSE 2 END
Hasilnya akan menjadi Daftar yang dimulai dengan baris "IsGen = 0", diikuti oleh baris "IsGen = 1" dan semua baris lainnya diakhiri.
Anda dapat menambahkan lebih banyak parameter pesanan di akhir:
SELECT col1 , col2 FROM tbl_Bill WHERE col1 = 0 ORDER BY -- order by case-statement CASE WHEN tbl_Bill.IsGen = 0 THEN 0 WHEN tbl_Bill.IsGen = 1 THEN 1 ELSE 2 END, col1, col2
sumber
Bagi seseorang yang baru mengenal ORDER BY dengan CASE ini semoga bermanfaat
ORDER BY CASE WHEN GRADE = 'A' THEN 0 WHEN GRADE = 'B' THEN 1 ELSE 2 END
sumber
Anda dapat menggunakan posisi (teks dalam teks) secara berurutan untuk mengurutkan urutan
sumber