sql >> Base de Datos >  >> RDS >> Database

Cómo escribir una cláusula ORDER BY con excepciones usando SQL

En SQL, el ORDER BY La cláusula se usa comúnmente para ordenar los resultados de una consulta. Le permite seleccionar una o más columnas para ordenar los resultados y, en la mayoría de los casos, probablemente sea todo lo que necesita.

Pero, ¿y si necesita hacer una excepción?

¿Qué sucede si desea que los resultados se ordenen alfabéticamente, excepto por una fila? ¿O varias filas?

O tal vez simplemente quiera poner cualquier valor NULL al final, mientras ordena los resultados que no son NULL.

De cualquier manera, hay un buen truco que puedes usar que te permitirá hacer esto. Y lo bueno es que es simple.

Puede atender todos los escenarios anteriores agregando un CASE expresión a su ORDER BY cláusula.

Ejemplo 1:mover "Otro" al final

Supongamos que ejecutamos la siguiente consulta en una tabla que contiene géneros musicales.

SELECT Genre 
FROM MusicGenres
ORDER BY Genre ASC;

Resultado:

+---------+
| Genre   |
|---------|
| Blues   |
| Country |
| Hip Hop |
| Jazz    |
| Metal   |
| Other   |
| Pop     |
| Rap     |
| Rock    |
+---------+

En este caso, ordenamos los resultados por Genre columna, en orden ascendente.

Esto está bien excepto por una cosa. El género llamado Otro . ¿No sería bueno si pudiéramos mover Otro hasta el fondo?

Podemos lograr esto con el CASE expresión. Por lo tanto, podemos tomar la consulta anterior y modificar su ORDER BY cláusula de la siguiente manera.

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

Ejemplo 2:mover valores NULL al final

Si su tabla contiene alguno de esos molestos valores NULL, encontrará que insisten en permanecer en la parte superior cuando ordena en orden ascendente.

Una vez más, CASE expresión al rescate!

Imaginemos que la tabla anterior contiene un par de valores NULL. Y cuando ejecutamos nuestra consulta, se parece más a esto:

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

Así que ahora queremos mover los valores NULL a la parte inferior, incluso más bajos que Otro .

Podemos hacerlo con la siguiente 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    |
+---------+

En este ejemplo, usamos un CASE diferente formato. En este ejemplo usamos un buscado CASE expresión , a diferencia del ejemplo anterior que usaba un simple CASE expresión .

El CASE buscado expresión evalúa un conjunto de expresiones booleanas para determinar el resultado.

El CASE simple expresión, por otro lado, compara una expresión con un conjunto de expresiones simples para determinar el resultado.

El CASE simple expresión tiene una expresión de entrada al lado del CASE palabra clave, mientras que el CASE buscado expresión no.

Ejemplo 3:arreglar ciertas filas en la parte superior

Ahora imagine que queremos tener una o más filas que estén siempre en la parte superior de los resultados, independientemente de dónde encajen dentro del orden de los resultados más amplios.

Por ejemplo:

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

Estos resultados están ordenados por ArtistName y luego por AlbumName .

Pero la discográfica ha decidido que quieren hacer una promoción especial para Tom Jones . Y por eso quieren a Tom Jones para que aparezcan en la parte superior de los resultados, pero luego todos los resultados restantes deben ordenarse tal cual:alfabéticamente por el nombre del artista, luego por el nombre del álbum.

En este caso, podemos hacer lo siguiente:

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