Database
 sql >> Database >  >> RDS >> Database

Come scrivere una clausola ORDER BY con eccezioni utilizzando SQL

In SQL, il ORDER BY La clausola è comunemente usata per ordinare i risultati di una query. Ti consente di selezionare una o più colonne per ordinare i risultati e, nella maggior parte dei casi, è probabilmente tutto ciò di cui hai bisogno.

Ma cosa succede se devi fare un'eccezione?

Cosa succede se si desidera che i risultati siano ordinati in ordine alfabetico, ad eccezione di una riga? O più righe?

O forse vuoi semplicemente mettere alla fine tutti i valori NULL, ordinando i risultati non NULL.

Ad ogni modo, c'è un trucco accurato che puoi usare che ti consentirà di farlo. E il bello è che è semplice.

Puoi soddisfare tutti gli scenari di cui sopra aggiungendo un CASE espressione al tuo ORDER BY clausola.

Esempio 1 – Sposta "Altro" in basso

Supponiamo di eseguire la seguente query su una tabella contenente generi musicali.

SELECT Genre 
FROM MusicGenres
ORDER BY Genre ASC;

Risultato:

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

In questo caso, ordiniamo i risultati in base al Genre colonna, in ordine crescente.

Questo va bene tranne per una cosa. Il genere chiamato Altro . Non sarebbe bello se potessimo spostare Altro fino in fondo?

Possiamo raggiungere questo obiettivo con il CASE espressione. Pertanto, possiamo prendere la query di cui sopra e modificarne il ORDER BY clausola come segue.

SELECT Genre
FROM MusicGenres
ORDER BY 
    CASE Genre
        WHEN 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC;

Risultato:

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

Esempio 2 – Sposta NULL in basso

Se la tua tabella contiene uno di quei fastidiosi valori NULL, scoprirai che insisteranno per rimanere in cima quando ordini in ordine crescente.

Ancora una volta, CASE espressione in soccorso!

Immaginiamo che la tabella sopra contenga un paio di valori NULL. E quando eseguiamo la nostra query, sembra più simile a questa:

SELECT Genre
FROM MusicGenres
ORDER BY 
    CASE Genre
        WHEN 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC;

Risultato:

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

Quindi ora vogliamo spostare i valori NULL in basso, anche più in basso di Altro .

Possiamo farlo con la seguente query.

SELECT Genre
FROM MusicGenres
ORDER BY 
    CASE
        WHEN Genre IS NULL THEN 2
        WHEN Genre = 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC;

Risultato:

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

In questo esempio, abbiamo usato un diverso CASE formato. In questo esempio abbiamo utilizzato un CASE cercato espressione , al contrario dell'esempio precedente che utilizzava un semplice CASE espressione .

Il CASE cercato expression valuta un insieme di espressioni booleane per determinare il risultato.

Il semplice CASE expression, d'altra parte, confronta un'espressione con un insieme di espressioni semplici per determinare il risultato.

Il semplice CASE expression ha un'espressione di input accanto a CASE parola chiave, mentre il CASE cercato l'espressione no.

Esempio 3 – Correggi alcune righe in alto

Ora immagina di voler avere una o più righe che sono sempre in cima ai risultati, indipendentemente da dove si adattano all'ordine dei risultati più ampi.

Ad esempio:

SELECT * FROM vAlbums
ORDER BY ArtistName ASC, AlbumName ASC;

Risultato:

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

Questi risultati sono ordinati per ArtistName , quindi da AlbumName .

Ma la casa discografica ha deciso di voler fare una promozione speciale per Tom Jones . E quindi vogliono Tom Jones per apparire in cima ai risultati, ma poi tutti i risultati rimanenti devono essere ordinati così com'è, in ordine alfabetico in base al nome dell'artista, quindi in base al nome dell'album.

In questo caso, possiamo fare quanto segue:

SELECT * FROM vAlbums
ORDER BY 
    CASE ArtistName
        WHEN 'Tom Jones' THEN 0
        ELSE 1
    END,
    ArtistName ASC, AlbumName ASC;

Risultato:

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