Může nastat situace, kdy je v dotazu SQL požadováno konkrétní pořadí, které nelze provést pomocí ASC nebo DESC nebo pomocí speciálního třídicího pole. MySQL má funkci ORDER BY FIELD, kterou lze k tomuto účelu použít.
Příkladová data
Příkladová data v tomto příspěvku používají moji příkladovou tabulku ovoce. Jedná se o poněkud jednoduchou tabulku, ale lze ji docela dobře použít k ilustraci toho, co je v tomto příspěvku uvedeno.
Řazení podle hodnot konkrétních polí
Tabulka ovoce má pole „název“ s následujícími jedinečnými hodnotami: Jablko, Banán, Pomeranč, Hruška. Každá z těchto jedinečných hodnot má sadu odrůd.
Řekněme pro představu, že chceme seřadit data v určitém pořadí podle Banán, Jablko, Hruška, Pomeranč a pak podle jejich odrůd. To není možné provést pomocí běžné klauzule ORDER BY, protože vzestupné nebo sestupné řazení na tomto poli nebude fungovat. Potřebovali bychom buď nějakou formu třídicího sloupce, nebo jinou alternativu.
Pomocí funkce FIELD( ) v klauzuli ORDER BY toho můžeme dosáhnout. Funguje tak, že zadáme sloupec, podle kterého se má řadit, a pak hodnoty, které se mají seřadit. Například:
SELECT * FROM fruit ORDER BY FIELD(name, 'Banana', 'Apple', 'Pear', 'Orange'), variety;
Výsledná data z příkladové tabulky vypadají takto:
+----------+--------+---------------------+| 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 |+----------+--------+---------------------+
Závada
Při použití této funkce existuje drobná „závada“. Všechny hodnoty, které jsou ve sloupci a nejsou ve funkci FIELD(), se objeví ve víceméně náhodném pořadí před zadanými hodnotami. Například při zadání pouze Apple a Banana:
SELECT * FROM fruit ORDER BY FIELD(name, 'Banana', 'Apple') DESC, variety;
Výsledkem je:
+----------+--------+---------------------+| 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 |+----------+--------+---------------------+
Řešení „gotcha“
Ačkoli byste tuto funkci normálně použili pouze tehdy, když jsou známy přesné sloupce, řešením je obrátit pořadí zadaných polí a seřadit je sestupně a pak provést druhé třídění na stejném poli.
Následující příklad, navzdory tomu, jak vypadá, ve skutečnosti řadí v pořadí Banana, pak Apple a pak ostatní jména vzestupně:
SELECT * FROM fruit ORDER BY FIELD(name, 'Apple', 'Banana') DESC, name, variety;
Výsledkem je:
+----------+--------+---------------------+| 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 |+----------+--------+---------------------+
Toto může být užitečné řešení, pokud se určitá sada řádků musí objevit před ostatními v souboru výsledků, ale normálně by se neobjevila jako první při použití řazení ASC nebo DESC.