Se poate întâmpla uneori să fie necesară o ordine specifică într-o interogare SQL care nu poate fi realizată folosind ASC sau DESC sau folosind un câmp de sortare special. MySQL are o funcție ORDER BY FIELD care poate fi utilizată pentru a face acest lucru.
Date de exemplu
Datele de exemplu din această postare utilizează tabelul meu de exemplu de fructe. Acesta este un tabel oarecum simplu, dar poate fi folosit pentru a ilustra destul de bine punctul din această postare.
Ordonare după valorile specifice ale câmpurilor
Tabela de fructe are un câmp „nume” cu următoarele valori unice: Apple, Banana, Orange, Pear. Fiecare dintre aceste valori unice are un set de soiuri.
Să spunem, de dragul discuției, că dorim să ordonăm datele într-o ordine specifică după Banană, Măr, Pară, Portocală și apoi după soiurile acestora. Nu este posibil să facem acest lucru folosind o clauză ORDER BY obișnuită, deoarece o sortare ascendentă sau descendentă pe acest câmp nu va funcționa. Am avea nevoie fie de o formă de coloană de sortare, fie de o altă alternativă.
Utilizând funcția FIELD( ) în clauza ORDER BY putem realiza acest lucru. Aceasta funcționează prin specificarea coloanei după care se va sorta și apoi a valorilor care trebuie sortate în ordine. De exemplu:
SELECT * FROM fruit ORDER BY FIELD(name, 'Banana', 'Apple', 'Pear', 'Orange'), variety;
Datele rezultate din tabelul de exemplu arată astfel:
+----------+--------+---------------------+| fruit_id | name | variety |+----------+--------+---------------------+| 11 | Banana | Burro || 12 | Banana | Cavendish || 10 | Banana | Plantain || 6 | Apple | Cox's Orange Pippin || 7 | Apple | Granny Smith || 1 | Apple | Red Delicious || 8 | Pear | Anjou || 4 | Pear | Bartlett || 2 | Pear | Comice || 5 | Orange | Blood || 3 | Orange | Navel || 9 | Orange | Valencia |+----------+--------+---------------------+
Ceea ce se întâmplă
Există o ușoară „scăpare” atunci când se utilizează această funcție. Orice valoare care se află în coloană și care nu se află în funcția FIELD() va apărea într-o ordine mai mult sau mai puțin aleatorie înaintea valorilor specificate. De exemplu, dacă se specifică doar Apple și Banana:
SELECT * FROM fruit ORDER BY FIELD(name, 'Banana', 'Apple') DESC, variety;
Aceasta are ca rezultat:
+----------+--------+---------------------+| fruit_id | name | variety |+----------+--------+---------------------+| 6 | Apple | Cox's Orange Pippin || 7 | Apple | Granny Smith || 1 | Apple | Red Delicious || 11 | Banana | Burro || 12 | Banana | Cavendish || 10 | Banana | Plantain || 8 | Pear | Anjou || 4 | Pear | Bartlett || 5 | Orange | Blood || 2 | Pear | Comice || 3 | Orange | Navel || 9 | Orange | Valencia |+----------+--------+---------------------+
O soluție pentru gotcha
Deși în mod normal veți folosi această funcție doar atunci când coloanele exacte sunt cunoscute, o soluție este să inversați ordinea câmpurilor specificate și să le ordonați în ordine descrescătoare, iar apoi să faceți o a doua sortare pe același câmp.
Exemplul următor, în ciuda modului în care arată, sortează de fapt în ordinea Banana, apoi Apple și apoi celelalte nume în ordine crescătoare:
SELECT * FROM fruit ORDER BY FIELD(name, 'Apple', 'Banana') DESC, name, variety;
Aceasta are ca rezultat:
+----------+--------+---------------------+| fruit_id | name | variety |+----------+--------+---------------------+| 11 | Banana | Burro || 12 | Banana | Cavendish || 10 | Banana | Plantain || 6 | Apple | Cox's Orange Pippin || 7 | Apple | Granny Smith || 1 | Apple | Red Delicious || 5 | Orange | Blood || 3 | Orange | Navel || 9 | Orange | Valencia || 8 | Pear | Anjou || 4 | Pear | Bartlett || 2 | Pear | Comice |+----------+--------+---------------------+
Aceasta poate fi o soluție utilă dacă un anumit set de rânduri trebuie să apară înaintea celorlalte în setul de rezultate, dar în mod normal nu ar apărea primul atunci când se folosește o ordine de sortare ASC sau DESC.