SQL permet d’utiliser l’expression CASE Ã bien des endroits. Un des endroits les moins attendu pour y placer la structure CASE est la clause ORDER BY…
Mais cette astuce permet de faire un tri conditionnel.
Illustrons notre propos avec un exemple :
CREATE TABLE T_FACTURE
(FCT_CATEGORIE VARCHAR(16),
FCT_MONTANT DECIMAL(16,2))
INSERT INTO T_FACTURE VALUES ('Boucherie', 123.45)
INSERT INTO T_FACTURE VALUES ('Boulangerie', 789.45)
INSERT INTO T_FACTURE VALUES ('Charcuterie', 5426.21)
INSERT INTO T_FACTURE VALUES ('Voyage', 9523.21)
INSERT INTO T_FACTURE VALUES ('Boulangerie', 64.45)
INSERT INTO T_FACTURE VALUES ('Boucherie', 1584.45)
INSERT INTO T_FACTURE VALUES ('Charcuterie', 5426.21)
INSERT INTO T_FACTURE VALUES ('Boucherie', 9684.45)
SELECT FCT_CATEGORIE, SUM(FCT_MONTANT) AS CA
FROM T_FACTURE
GROUP BY FCT_CATEGORIE
UNION ALL
SELECT 'TOTAL', SUM(FCT_MONTANT) AS CA
FROM T_FACTURE
ORDER BY 1
FCT_CATEGORIE CA
---------------- -----------------
Boucherie 11392.35
Boulangerie 853.90
Charcuterie 10852.42
TOTAL 32621.88
Voyage 9523.21
Comment faire en sorte que la ligne de totalisation se retrouve toujours en dernière ligne, malgré que nous voulions les autres catégories triées par ordre alphabétique ?
C’est grâce au CASE que nous allons pouvoir répondre à cette problématique :
SELECT *
FROM (SELECT FCT_CATEGORIE, SUM(FCT_MONTANT) AS CA
FROM T_FACTURE
GROUP BY FCT_CATEGORIE
UNION ALL
SELECT 'TOTAL' AS FCT_CATEGORIE, SUM(FCT_MONTANT) AS CA
FROM T_FACTURE) AS T
ORDER BY CASE WHEN FCT_CATEGORIE = 'TOTAL' THEN 1 ELSE 0 END, 1
FCT_CATEGORIE CA
---------------- ------------
Boucherie 11392.35
Boulangerie 853.90
Charcuterie 10852.42
Voyage 9523.21
TOTAL 32621.88
CQFD !
Frédéric BROUARD – SQLpro – MVP SQL Server
Spécialiste SQL/BD modélisation de données
SQL & SGBDR http://sqlpro.developpez.com/
Expert SQL Server : http://www.sqlspot.com
audits – optimisation – tuning – formation
« un CASE nécessite forcément un traitement logique pour obtenir l’information, qui devra être effectué pour chaque ligne, »
Ceci n’est pas vrai sur tous les SGBDR. par exemple SQL Server optimise le CASE.
A +
…> un CASE nécessite forcément un traitement logique pour obtenir l’information, qui devra être effectué pour chaque ligne,
Non, pas au niveau du plan de requête, mais un CASE nécessite forcément un traitement logique pour obtenir l’information, qui devra être effectué pour chaque ligne, alors que avec Select 1, la valeur est disponible directement.
mais je n’ai pas mesuré
Je ne crois pas qu’il y aura la moindre différence d’exécution au niveau des plans de requête !
A +
C’est bien pour un petit nombre de lignes, mais si il y a beaucoup de données, au niveau performance, il vaut mieux faire :
SELECT 0 as tri, FCT_CATEGORIE, SUM(FCT_MONTANT) AS CA
FROM T_FACTURE
GROUP BY FCT_CATEGORIE
UNION ALL
SELECT 1 as tri, ‘TOTAL’, SUM(FCT_MONTANT) AS CA
FROM T_FACTURE
ORDER BY tri