Database
 sql >> Base de Dados >  >> RDS >> Database

Como escrever uma cláusula ORDER BY com exceções usando SQL


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     |
+------------------------+--------------------------+---------+