Mengurutkan berdasarkan nilai bidang tertentu terlebih dahulu


93

Saya memiliki tabel dengan 3 kolom:

id | name | priority
--------------------
 1 | core  |   10
 2 | core  |   9
 3 | other |   8
 4 | board |   7
 5 | board |   6
 6 | core  |   4

Saya ingin memesan set hasil menggunakan prioritytetapi pertama-tama baris yang memiliki name=corebahkan jika memiliki prioritas lebih rendah. Hasilnya akan terlihat seperti ini

id | name | priority
--------------------
 6 | core  |   4
 2 | core  |   9
 1 | core  |   10
 5 | board |   6
 4 | board |   7
 3 | other |   8

Jawaban:


160

Ada juga fungsi MySQLFIELD .

Jika Anda ingin menyelesaikan pengurutan untuk semua kemungkinan nilai:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core", "board", "other")

Jika Anda hanya peduli bahwa "inti" adalah yang pertama dan nilai lainnya tidak penting:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC

Jika Anda ingin mengurutkan berdasarkan "inti" terlebih dahulu, dan bidang lainnya dalam urutan normal:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC, priority

Namun, ada beberapa peringatan di sini:

Pertama, saya cukup yakin ini adalah fungsi hanya-mysql - pertanyaannya diberi tag mysql, tetapi Anda tidak pernah tahu.

Kedua, perhatikan cara FIELD()kerjanya: ia mengembalikan indeks nilai berbasis satu - dalam kasus FIELD(priority, "core"), ia akan mengembalikan 1 jika "inti" adalah nilainya. Jika nilai bidang tidak ada dalam daftar, itu mengembalikan nol . Inilah mengapa DESCperlu kecuali Anda menentukan semua kemungkinan nilai.


5
Setelah sekitar 5 tahun saya mengubah jawaban yang diterima untuk yang satu ini karena lebih bersih dan lebih cepat.
Omid

setara db2?
Cybermonk

Ini berhasil untuk saya, ingin mengajukan satu pertanyaan lagi tentang bagaimana menangani Jika kolom 'prioritas' berisi nilai-nilai seperti misalnya: 'inti bumi', 'papan baru' dll. Di sini kolom tidak berisi nilai pasti, dapatkah kita menulis sesuatu seperti %inti%?
Jayanth Suvarna

@JayanthSuvarna: melihat dokumen MySQL FIELD (), saya cukup yakin tidak ada cara untuk mengevaluasi ini sebagai substring, karena setiap argumen harus berupa semacam string. Mungkin ada beberapa fungsi manipulasi string yang bisa membantu, tapi saya tidak yakin.
Nerdmaster

Terima kasih, sobat. Anda membuat hari saya.
BEingprabhU

92

Umumnya bisa Anda lakukan

select * from your_table
order by case when name = 'core' then 1 else 2 end,
         priority 

Apalagi di MySQL juga bisa Anda lakukan

select * from your_table
order by name <> 'core',
         priority 

Karena hasil perbandingan di MySQL adalah 0atau 1dan Anda dapat mengurutkan berdasarkan hasil itu.


1
apa 1dan 2artinya disini?
Niraj Chauhan

1
Saya memiliki sekitar 3000 baris untuk disortir. Dalam kasus saya, solusi @ Ayman-Hourieh di stackoverflow.com/questions/958627/… membutuhkan separuh waktu dibandingkan dengan solusi ini.
hari

@nightlyop: Bagus. Hanya satu catatan: Solusi yang lebih cepat khusus untuk MySQL.
juergen d

1dan 2hanya 2 angka yang saya gunakan untuk mengurutkan data. Bisa jadi 3dan 4atau sesuatu yang lain.
juergen d

Bagaimana jika ada %di WHEREklausa? Suka . . . WHERE name LIKE '%sth%' . . .? stackoverflow.com/questions/41303379/…
tumpukan

6

Salah satu cara untuk memberi preferensi pada baris tertentu adalah dengan menambahkan angka besar ke prioritasnya. Anda dapat melakukan ini dengan CASEpernyataan:

  select id, name, priority
    from mytable
order by priority + CASE WHEN name='core' THEN 1000 ELSE 0 END desc

Demo: http://www.sqlfiddle.com/#!2/753ee/1


5

Ini berfungsi untuk saya menggunakan Postgres 9+:

SELECT *
FROM your_table
ORDER BY name = 'core' DESC, priority DESC

Mau menjelaskan -1? Error + versi Postgres?
Vojtech Vitek

3

Salah satu caranya adalah ini:

select id, name, priority from table a
order by case when name='core' then -1 else priority end asc, priority asc

1
Tidakkah ini akan menghilangkan urutan corebaris?
mellamokb

1
SELECT * FROM cars_new WHERE status = '1' and car_hide !='1' and cname IN ('Executive Car','Saloon','MPV+','MPV5') ORDER BY FIELD(cname, 'Executive Car', 'Saloon','MPV+','mpv5')

3
Meskipun kode Anda mungkin merupakan jawaban atas pertanyaan tersebut, lebih baik memberikan penjelasan tentangnya.
Mehraban

0

melakukan hal ini:

SELECT * FROM table ORDER BY column `name`+0 ASC

Menambahkan +0 berarti:

0, 10, 11, 2, 3, 4

menjadi :

0, 2, 3, 4, 10, 11

Teknik ini untuk mengubah string menjadi angka. Itu tidak menjawab pertanyaan OP. (Namun, tanpa melihat tipe data priority, saya tidak dapat mengatakan apakah itu harus menjadi bagian dari solusi lengkap.)
Rick James

0

Gunakan ini:

SELECT * 
FROM tablename 
ORDER BY priority desc, FIELD(name, "core")
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.