MySQL : order by selon la valeur des champs

Personnaliser l'algorithme de tri grâce à coalesce

01 mars 2017

Coalesce est une fonction SQL qui prend une liste de paramètres en entrée et retourne le premier non null. Si tous les paramètres sont null, null est retourné.

Vous pouvez utiliser un coalesce dans un order by pour trier différemment selon qu'un champ soit vide ou contienne une valeur spécifique.

Par exemple prenons le cas de paiements. Nous disposons d'une table "payment" dans laquelle nous avons plusieurs dates, chacune représentant une étape de la vie d'un paiement : date de demande de prélèvement, date réelle de prélèvement, date de remboursement. On veut trier les paiements par ordre de leur dernière opération : d'abord la date de remboursement puis la date de prélèvement puis la date de demande de prélèvement puis la date de création de la ligne dans la table. Pour chaque ligne de la table, le coalesce analysera la situation et prendra en compte l'une de ces dates afin de trier.

payment_idpayment_methoddate_createdate_demanddate_debitdate_refund
1bank card2017-03-01 13:00:002017-03-01 13:02:002017-03-01 14:00:00NULL
2bank card2016-12-21 08:00:002016-12-21 08:02:002016-12-21 09:00:002017-02-28 17:00:00
3bank card2017-02-01 16:00:002017-02-01 16:02:002017-02-01 17:00:002017-02-28 20:00:00
4direct debit2017-02-25 13:36:002017-02-25 13:40:002017-02-25 13:40:02NULL
5direct debit2017-03-01 13:36:002017-03-01 13:37:00NULLNULL

Trier avec des champs vides

SELECT
        *
FROM
        payment
ORDER BY
        COALESCE (date_refund, date_debit, date_demand, date_create) DESC

/* Pour vous assurer que cette requête fonctionne vous pouvez jouer */

SELECT
        COALESCE (date_refund, date_debit, date_demand, date_create) AS last_operation_date,
        p.*
FROM
        payment p
ORDER BY
        last_operation_date DESC

Maintenant supposons que l'on veuille ajouter un filtre pour que le tri se fasse différemment dans certains cas. Par exemple certains moyens de paiement n'ont pas de vraie date_demand car ils réalisent en temps réel le débit, cette colonne est renseignée avec une valeur mais nous ne voulons pas la prendre en compte. Nous allons filtrer sur le champ payment_method.

Trier avec des valeurs particulières

SELECT
        COALESCE(
                date_refund,
                date_debit,
                IF(payment_method = "direct debit", NULL, date_demand),
                date_create
        ) AS last_operation_date,
        p.*
FROM
        payment p
ORDER BY
        last_operation_date DESC

Vous pouvez constater que la date_demand a bien été ignorée pour le cas du "direct debit".

A bientôt !

Par
Créateur et administrateur.

Dans la même catégorie

MySQL: comment faire une requête sur la description d'une table
MySQL ON DUPLICATE KEY UPDATE : insérer ou mettre à jour une ligne
MySQL : une table pivot dynamique
SQL : faire un select sur une liste de valeurs
MySQL : créer une table à partir d'un select
MySQL : copier une table
MySQL REPLACE : insérer ou mettre à jour une ligne
MSSQL : Trouver le message qui correspond à un code d'erreur
MySQL : Comment autoriser les connexions distantes ?
MySQL : Quand l'encodage veut votre peau !
mysqldump : Comment ne pas prendre en compte une table ?
Dump d'une table MySQL avec une requête
MySQL en ligne de commande
DELETE avec des jointures
Sauvegarder automatiquement une base de données MySQL

Commentaire(s)