W3docs

MySQL Order By

Impara a ordinare i risultati delle query MySQL in Python con ORDER BY: crescente, decrescente, multicolonna e in combinazione con WHERE e LIMIT.

Questo capitolo mostra come ordinare i risultati delle query MySQL in Python usando la clausola ORDER BY. Imparerai a ordinare in modo crescente e decrescente, a ordinare per più colonne, a combinare ORDER BY con WHERE e LIMIT, e ad applicare le best practice di Python come le query parametrizzate e la corretta gestione degli errori.

Cosa fa ORDER BY

La clausola ORDER BY indica a MySQL di restituire le righe in una sequenza specificata anziché nell'ordine di archiviazione (che è imprevedibile). Puoi ordinare per una o più colonne, in ordine crescente (ASC) o decrescente (DESC).

SELECT column1, column2
FROM table_name
ORDER BY column1 ASC, column2 DESC;

Regole fondamentali:

  • ASC (crescente, A → Z, 0 → 9) è il valore predefinito — puoi ometterlo.
  • DESC (decrescente, Z → A, 9 → 0) deve essere indicato esplicitamente.
  • Più colonne sono separate da virgole; MySQL ordina prima per la prima colonna, poi usa la colonna successiva per risolvere i pareggi.
  • I valori NULL vengono ordinati prima dei valori non NULL nell'ordine ASC e dopo di essi nell'ordine DESC.

Prerequisiti

È necessario il pacchetto mysql-connector-python. Installalo una volta con pip:

pip install mysql-connector-python

Tutti gli esempi seguenti presuppongono una tabella customers con almeno le colonne id, name e address. Consulta Python MySQL – Create Table se devi crearla prima.

Ordinamento crescente (predefinito)

L'ordine crescente è quello predefinito, quindi ASC è facoltativo. La query seguente restituisce tutti i clienti ordinati alfabeticamente per nome:

import mysql.connector
from mysql.connector import Error

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    mycursor.execute("SELECT * FROM customers ORDER BY name")

    for row in mycursor.fetchall():
        print(row)

except Error as e:
    print(f"Database error: {e}")
finally:
    if mycursor:
        mycursor.close()
    if mydb.is_connected():
        mydb.close()

Il blocco try / except / finally garantisce che la connessione venga sempre chiusa, anche in caso di errore.

Ordinamento decrescente

Aggiungi DESC dopo il nome della colonna per invertire l'ordine. Questo restituisce i clienti ordinati Z → A:

import mysql.connector
from mysql.connector import Error

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    mycursor.execute("SELECT * FROM customers ORDER BY name DESC")

    for row in mycursor.fetchall():
        print(row)

except Error as e:
    print(f"Database error: {e}")
finally:
    if mycursor:
        mycursor.close()
    if mydb.is_connected():
        mydb.close()

Ordinamento per più colonne

Quando la prima colonna di ordinamento contiene valori uguali, MySQL usa la seconda colonna per risolvere i pareggi. Ciò è utile quando, ad esempio, vuoi i clienti ordinati prima per città e poi per nome all'interno di ciascuna città:

import mysql.connector
from mysql.connector import Error

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    # Sort by address (city) ascending, then by name ascending within each city
    mycursor.execute("SELECT * FROM customers ORDER BY address ASC, name ASC")

    for row in mycursor.fetchall():
        print(row)

except Error as e:
    print(f"Database error: {e}")
finally:
    if mycursor:
        mycursor.close()
    if mydb.is_connected():
        mydb.close()

Ogni colonna in un ordinamento multicolonna può avere la propria direzione:

-- Most recent orders first; within the same date, highest total first
SELECT * FROM orders ORDER BY order_date DESC, total_amount DESC;

Combinare ORDER BY con WHERE

ORDER BY viene applicato dopo che WHERE ha filtrato le righe. Usa le query parametrizzate (il segnaposto %s) per passare i valori in modo sicuro — non formattare mai l'input dell'utente direttamente nella stringa SQL.

import mysql.connector
from mysql.connector import Error

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    # Find all customers in London, sorted by name
    sql = "SELECT * FROM customers WHERE address = %s ORDER BY name ASC"
    val = ("London",)
    mycursor.execute(sql, val)

    for row in mycursor.fetchall():
        print(row)

except Error as e:
    print(f"Database error: {e}")
finally:
    if mycursor:
        mycursor.close()
    if mydb.is_connected():
        mydb.close()

Il segnaposto %s viene sostituito da MySQL (non dalla formattazione delle stringhe di Python), il che previene l'SQL injection indipendentemente dal valore contenuto.

Combinare ORDER BY con LIMIT

Usa LIMIT insieme a ORDER BY per implementare pattern come "i primi N record" o la paginazione. L'ordinamento deve precedere LIMIT nell'istruzione SQL.

import mysql.connector
from mysql.connector import Error

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="yourusername",
        password="yourpassword",
        database="mydatabase"
    )
    mycursor = mydb.cursor()

    # The 5 customers whose names come first alphabetically
    mycursor.execute("SELECT * FROM customers ORDER BY name ASC LIMIT 5")

    for row in mycursor.fetchall():
        print(row)

except Error as e:
    print(f"Database error: {e}")
finally:
    if mycursor:
        mycursor.close()
    if mydb.is_connected():
        mydb.close()

Per la paginazione (saltando le pagine precedenti), aggiungi OFFSET:

-- Page 2: rows 6–10
SELECT * FROM customers ORDER BY name ASC LIMIT 5 OFFSET 5;

Consulta Python MySQL – Limit per una guida completa su LIMIT e OFFSET.

Recuperare una riga o tutte le righe

Dopo aver eseguito una query con ORDER BY puoi recuperare i risultati in diversi modi:

MetodoRestituisceDa usare quando
fetchall()Lista di tutte le tuple corrispondentiIl set di risultati è abbastanza piccolo da tenere in memoria
fetchone()Prima riga come tupla (o None)Hai bisogno solo del primo record
fetchmany(n)Lista dei successivi n righeSi elabora un grande set di risultati in blocchi

Esempio — recupera solo il cliente alfabeticamente primo:

mycursor.execute("SELECT * FROM customers ORDER BY name ASC")
top = mycursor.fetchone()
print(top)  # e.g. (1, 'Alice', 'London')

Errori comuni

Ordinamento di stringhe come numeri. Se una colonna memorizza numeri come VARCHAR, MySQL li ordina lessicograficamente ('10' viene prima di '9'). Converti la colonna quando hai bisogno dell'ordine numerico:

SELECT * FROM products ORDER BY CAST(price AS DECIMAL(10,2)) ASC;

L'ordinamento senza ORDER BY è non deterministico. MySQL non garantisce l'ordine delle righe a meno che non si specifichi ORDER BY. Fare affidamento sull'ordine di inserimento causerà problemi imprevedibili man mano che la tabella cresce o gli indici cambiano.

Gli alias di colonna funzionano in ORDER BY. Se definisci un alias in SELECT, puoi usarlo in ORDER BY:

SELECT name, address AS city FROM customers ORDER BY city ASC;

Posizione in ORDER BY. Puoi fare riferimento a una colonna tramite la sua posizione nell'elenco SELECT (ad es. ORDER BY 1), ma questo è fragile — evitalo nel codice di produzione perché si rompe silenziosamente quando riordini le colonne.

Capitoli correlati

Was this page helpful?