В SQL, ORDER BY
клаузата обикновено се използва за подреждане на резултатите от заявка. Позволява ви да изберете една или повече колони, за да подредите резултатите и в повечето случаи вероятно това е всичко, от което се нуждаете.
Но какво ще стане, ако трябва да направите изключение?
Ами ако искате резултатите да бъдат подредени по азбучен ред, с изключение на един ред? Или няколко реда?
Или може би просто искате да поставите NULL стойности в края, докато подреждате резултатите, различни от NULL.
Така или иначе, има чист трик, който можете да използвате, който ще ви позволи да направите това. И добрата част е, че е просто.
Можете да се погрижите за всички горни сценарии, като добавите CASE
израз към вашия ORDER BY
клауза.
Пример 1 – Преместете „Друго“ в долната част
Да предположим, че изпълняваме следната заявка към таблица, съдържаща музикални жанрове.
SELECT Genre
FROM MusicGenres
ORDER BY Genre ASC;
Резултат:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Other | | Pop | | Rap | | Rock | +---------+
В този случай подреждаме резултатите по Genre
колона във възходящ ред.
Това е добре с изключение на едно нещо. Жанрът, наречен Други . Не би ли било хубаво, ако можем да преместим Други до дъното?
Можем да постигнем това с CASE
изразяване. Следователно можем да приемем горната заявка и да променим нейната ORDER BY
клауза, както следва.
SELECT Genre
FROM MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Резултат:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Pop | | Rap | | Rock | | Other | +---------+
Пример 2 – Преместване на NULL до дъното
Ако вашата таблица съдържа някоя от досадните стойности NULL, ще откриете, че те ще настояват да останат на върха, когато поръчвате във възходящ ред.
Още веднъж CASE
израз на помощ!
Нека си представим, че горната таблица съдържа няколко NULL стойности. И когато стартираме нашата заявка, тя изглежда по-скоро така:
SELECT Genre
FROM MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Резултат:
+---------+ | Genre | |---------| | NULL | | NULL | | Blues | | Hip Hop | | Jazz | | Metal | | Pop | | Rock | | Other | +---------+
Така че сега искаме да преместим стойностите NULL на дъното – дори по-ниско от Други .
Можем да направим това със следната заявка.
SELECT Genre
FROM MusicGenres
ORDER BY
CASE
WHEN Genre IS NULL THEN 2
WHEN Genre = 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Резултат:
+---------+ | Genre | |---------| | Blues | | Hip Hop | | Jazz | | Metal | | Pop | | Rock | | Other | | NULL | | NULL | +---------+
В този пример използвахме различен CASE
формат. В този пример използвахме търсен CASE
израз , за разлика от предишния пример, който използва прост CASE
израз .
Търсеният CASE
Expression оценява набор от булеви изрази, за да определи резултата.
Простият CASE
израз, от друга страна, сравнява израз с набор от прости изрази, за да определи резултата.
Простият CASE
изразът има входен израз до CASE
ключова дума, докато търсеният CASE
изразът не.
Пример 3 – Фиксиране на определени редове отгоре
Сега си представете, че искаме да имаме един или повече реда, които винаги са в горната част на резултатите, независимо къде се вписват в подреждането на по-широките резултати.
Например:
SELECT * FROM vAlbums
ORDER BY ArtistName ASC, AlbumName ASC;
Резултат:
+------------------------+--------------------------+---------+ | ArtistName | AlbumName | Genre | |------------------------+--------------------------+---------| | AC/DC | Powerage | Rock | | Allan Holdsworth | All Night Wrong | Jazz | | Allan Holdsworth | The Sixteen Men of Tain | Jazz | | Buddy Rich | Big Swing Face | Jazz | | Devin Townsend | Casualties of Cool | Rock | | Devin Townsend | Epicloud | Rock | | Devin Townsend | Ziltoid the Omniscient | Rock | | Iron Maiden | Killers | Rock | | Iron Maiden | No Prayer for the Dying | Rock | | Iron Maiden | Piece of Mind | Rock | | Iron Maiden | Powerslave | Rock | | Iron Maiden | Somewhere in Time | Rock | | Jim Reeves | Singing Down the Lane | Country | | Michael Learns to Rock | Blue Night | Pop | | Michael Learns to Rock | Eternity | Pop | | Michael Learns to Rock | Scandinavia | Pop | | The Script | No Sound Without Silence | Pop | | Tom Jones | Along Came Jones | Pop | | Tom Jones | Long Lost Suitcase | Pop | | Tom Jones | Praise and Blame | Pop | +------------------------+--------------------------+---------+
Тези резултати са подредени по ArtistName
, а след това от AlbumName
.
Но звукозаписната компания реши, че искат да направят специална промоция за Том Джоунс . И така те искат Том Джоунс за да се появи в горната част на резултатите, но след това всички останали резултати трябва да бъдат подредени както са – по азбучен ред по името на изпълнителя, след това по името на албума.
В този случай можем да направим следното:
SELECT * FROM vAlbums
ORDER BY
CASE ArtistName
WHEN 'Tom Jones' THEN 0
ELSE 1
END,
ArtistName ASC, AlbumName ASC;
Резултат:
+------------------------+--------------------------+---------+ | ArtistName | AlbumName | Genre | |------------------------+--------------------------+---------| | Tom Jones | Along Came Jones | Pop | | Tom Jones | Long Lost Suitcase | Pop | | Tom Jones | Praise and Blame | Pop | | AC/DC | Powerage | Rock | | Allan Holdsworth | All Night Wrong | Jazz | | Allan Holdsworth | The Sixteen Men of Tain | Jazz | | Buddy Rich | Big Swing Face | Jazz | | Devin Townsend | Casualties of Cool | Rock | | Devin Townsend | Epicloud | Rock | | Devin Townsend | Ziltoid the Omniscient | Rock | | Iron Maiden | Killers | Rock | | Iron Maiden | No Prayer for the Dying | Rock | | Iron Maiden | Piece of Mind | Rock | | Iron Maiden | Powerslave | Rock | | Iron Maiden | Somewhere in Time | Rock | | Jim Reeves | Singing Down the Lane | Country | | Michael Learns to Rock | Blue Night | Pop | | Michael Learns to Rock | Eternity | Pop | | Michael Learns to Rock | Scandinavia | Pop | | The Script | No Sound Without Silence | Pop | +------------------------+--------------------------+---------+