Voi olla tilanteita, joissa SQL-kyselyssä tarvitaan tiettyä järjestystä, jota ei voida tehdä käyttämällä ASC- tai DESC-järjestystä tai erityistä lajittelukenttää. MySQL:ssä on ORDER BY FIELD -funktio, jota voidaan käyttää tähän tarkoitukseen.
Esimerkkiaineisto
Tämän postauksen esimerkkiaineistossa käytetään esimerkin hedelmätaulukkoa. Tämä on jokseenkin yksinkertainen taulukko, mutta sen avulla voidaan havainnollistaa tässä postauksessa esitettyä asiaa melko hyvin.
Järjestäminen tiettyjen kenttäarvojen mukaan
Hedelmätaulukossa on ”nimi”-kenttä, jolla on seuraavat yksilölliset arvot: Omena, Banaani, Appelsiini, Päärynä. Jokaisella näistä yksilöllisistä arvoista on joukko lajikkeita.
Esitettäköön väitteen vuoksi, että haluamme järjestää tiedot tiettyyn järjestykseen Banaani, Omena, Päärynä, Appelsiini ja sitten niiden lajikkeiden mukaan. Tätä ei voi tehdä tavallisella ORDER BY -lausekkeella, koska nouseva tai laskeva lajittelu tässä kentässä ei toimi. Tarvitsisimme joko jonkinlaisen lajittelusarakkeen tai jonkin muun vaihtoehdon.
Käyttämällä ORDER BY -lausekkeessa FIELD( ) -funktiota voimme saavuttaa tämän. Se toimii määrittämällä sarake, jonka mukaan lajitellaan, ja sitten arvot, jotka lajitellaan järjestyksessä. Esimerkiksi:
SELECT * FROM fruit ORDER BY FIELD(name, 'Banana', 'Apple', 'Pear', 'Orange'), variety;
Esimerkkitaulukon tuloksena saadut tiedot näyttävät tältä:
+----------+--------+---------------------+| 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 |+----------+--------+---------------------+
Sotku
Tätä funktiota käytettäessä on pieni ”sotku”. Kaikki sarakkeessa olevat arvot, jotka eivät ole FIELD()-funktiossa, näkyvät enemmän tai vähemmän satunnaisessa järjestyksessä ennen määritettyjä arvoja. Esimerkiksi määrittämällä vain Omena ja Banaani:
SELECT * FROM fruit ORDER BY FIELD(name, 'Banana', 'Apple') DESC, variety;
Tuloksena on:
+----------+--------+---------------------+| 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 |+----------+--------+---------------------+
Ratkaisu ongelmaan
Vaikka normaalisti käytät tätä funktiota vain silloin, kun tarkat sarakkeet ovat tiedossa, ratkaisuna on kääntää määritettyjen kenttien järjestys päinvastaiseksi ja järjestellä ne alenevaan järjestykseen ja tehdä toinen lajittelu samalle kentälle.
Seuraava esimerkki, huolimatta siitä miltä se näyttää, lajittelee itse asiassa järjestyksessä Banana, sitten Apple ja sitten muut nimet nousevassa järjestyksessä:
SELECT * FROM fruit ORDER BY FIELD(name, 'Apple', 'Banana') DESC, name, variety;
Tulokseksi saadaan:
+----------+--------+---------------------+| 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 |+----------+--------+---------------------+
Tämä voi olla käyttökelpoinen ratkaisu, jos tietyn joukon rivejä on tarpeen näkyä tulossarjassa ennen muita rivejä, mutta normaalisti se ei näkyisi ensimmäisenä käytettäessä ASC- tai DESC-lajittelujärjestystä.