No SQL, o
ORDER BY
A cláusula é comumente usada para ordenar os resultados de uma consulta. Ele permite que você selecione uma ou mais colunas para ordenar os resultados e, na maioria dos casos, provavelmente é tudo o que você precisa. Mas e se você precisar abrir uma exceção?
E se você quiser que os resultados sejam ordenados alfabeticamente, exceto por uma linha? Ou várias linhas?
Ou talvez você simplesmente queira colocar qualquer valor NULL no final, enquanto ordena os resultados não NULL.
De qualquer forma, há um truque legal que você pode usar que permitirá que você faça isso. E a parte boa é que é simples.
Você pode atender a todos os cenários acima adicionando um
CASE
expressão para o seu ORDER BY
cláusula. Exemplo 1 – Mover “Outro” para o fundo
Suponha que executemos a seguinte consulta em uma tabela contendo gêneros musicais.
SELECT Genre
FROM MusicGenres
ORDER BY Genre ASC;
Resultado:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Other | | Pop | | Rap | | Rock | +---------+
Neste caso, ordenamos os resultados pelo
Genre
coluna, em ordem crescente. Isso é bom, exceto por uma coisa. O gênero chamado Outro . Não seria bom se pudéssemos mover Outro ao fundo?
Podemos conseguir isso com o
CASE
expressão. Portanto, podemos pegar a consulta acima e modificar seu ORDER BY
cláusula como segue. SELECT Genre
FROM MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Resultado:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Pop | | Rap | | Rock | | Other | +---------+
Exemplo 2 – Mover NULLs para baixo
Se a sua tabela contiver algum desses valores NULL irritantes, você descobrirá que eles insistirão em permanecer no topo quando você fizer o pedido em ordem crescente.
Mais uma vez,
CASE
expressão para o resgate! Vamos imaginar que a tabela acima contém alguns valores NULL. E quando executamos nossa consulta, ela se parece mais com isso:
SELECT Genre
FROM MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Resultado:
+---------+ | Genre | |---------| | NULL | | NULL | | Blues | | Hip Hop | | Jazz | | Metal | | Pop | | Rock | | Other | +---------+
Então agora queremos mover os valores NULL para o fundo – ainda mais baixo que Outro .
Podemos fazer isso com a seguinte consulta.
SELECT Genre
FROM MusicGenres
ORDER BY
CASE
WHEN Genre IS NULL THEN 2
WHEN Genre = 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Resultado:
+---------+ | Genre | |---------| | Blues | | Hip Hop | | Jazz | | Metal | | Pop | | Rock | | Other | | NULL | | NULL | +---------+
Neste exemplo, usamos um
CASE
diferente formato. Neste exemplo, usamos um pesquisado CASE
expressão , ao contrário do exemplo anterior que usou um simples CASE
expressão . O
CASE
pesquisado expression avalia um conjunto de expressões booleanas para determinar o resultado. O simples
CASE
expressão, por outro lado, compara uma expressão a um conjunto de expressões simples para determinar o resultado. O simples
CASE
expressão tem uma expressão de entrada ao lado do CASE
palavra-chave, enquanto o CASE
pesquisado expressão não. Exemplo 3 – Corrigir certas linhas para o topo
Agora imagine que queremos ter uma ou mais linhas que estejam sempre na parte superior dos resultados, independentemente de onde elas se encaixem na ordenação dos resultados mais amplos.
Por exemplo:
SELECT * FROM vAlbums
ORDER BY ArtistName ASC, AlbumName ASC;
Resultado:
+------------------------+--------------------------+---------+ | 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 | +------------------------+--------------------------+---------+
Esses resultados são ordenados por
ArtistName
, e depois por AlbumName
. Mas a gravadora decidiu que quer fazer uma promoção especial para Tom Jones . Então eles querem Tom Jones para aparecer no topo dos resultados, mas todos os resultados restantes devem ser ordenados como estão – alfabeticamente pelo nome do artista e depois pelo nome do álbum.
Neste caso, podemos fazer o seguinte:
SELECT * FROM vAlbums
ORDER BY
CASE ArtistName
WHEN 'Tom Jones' THEN 0
ELSE 1
END,
ArtistName ASC, AlbumName ASC;
Resultado:
+------------------------+--------------------------+---------+ | 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 | +------------------------+--------------------------+---------+