PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 21/07/2014 13:31:35

guk92
Membre

Problème de ORDER BY sur un champ de type case when

Bonjour,


J'ai remarqué qu'il n'était pas possible de faire un "ORDER BY CASE WHEN mon_champ" lorsque "mon_champ" est le résultat d'un CASE WHEN.

Exemple :

SELECT
    case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end as alias1,
    champ2,
    -- Champs agrégats (SUM, COUNT etc)
FROM tables
GROUP BY 
    case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end, 
    champ2
ORDER BY case alias1 when 'tutu' then 1 when 'titi' then 2 when 'tutu' then 3 else 4 end, champ2

Est-ce que c'est normal ?


Cordialement,

Hors ligne

#2 21/07/2014 15:42:51

Re : Problème de ORDER BY sur un champ de type case when

Salut
Cela est très normale.
le regroupement (group by) et le trie (order by) s'appliquent sur l'ensemble des données (concernées). Par exemple, on dira "regrouper par localité, par sexe, par moyenne..." ou "trier (ordonner) par nom, par prénom...".
Il est alors illogique de dire "grouper par jean, par zidane..." ou "trier par paris, par mercedes..."
Pour faire simple et précis: pas de condition dans le group by ou le order by!
@+

Hors ligne

#3 21/07/2014 17:19:35

guk92
Membre

Re : Problème de ORDER BY sur un champ de type case when

Salut,




Si j'enlève la ligne ORDER BY, la requête est opérationnelle. Donc je peux faire un "GROUP BY case when", d'ailleurs si je fais un "GROUP BY case when" c'est parce que je ne peux pas faire de "GROUP BY alias1" : en effet les alias ne sont pas autorisés dans le GROUP BY.


Concernant le ORDER BY, bien sur qu'il sur qu'il est possible de mettre des conditions.


Le problème : Impossible de combiner "GROUP BY case when" et "ORDER BY case when".




Cordialement,

Hors ligne

#4 21/07/2014 19:04:54

gleu
Administrateur

Re : Problème de ORDER BY sur un champ de type case when

Ce dont vous n'avez pas le droit, c'est d'utiliser un des alias de la clause SELECT car ces alias ne sont connues qu'une fois le reste de la requête exécuté (ie, FROM, JOIN, WHERE, ORDER BY, GROUP BY, HAVING, etc).


Guillaume.

Hors ligne

#5 23/07/2014 17:46:10

guk92
Membre

Re : Problème de ORDER BY sur un champ de type case when

Bonjour,




Normalement on a le droit d'utiliser les alias dans ORDER BY. Je souhaiterais donc comprendre comment on gère un ORDER BY dans le cas où l'alias représente un case when.


Pour le moment, le seul moyen que j'ai trouvé de rendre l'exemple ci-dessus opérationnel, c'est de passer par une sous-requête :

SELECT * FROM (
    SELECT
        case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end as alias1,
        champ2,
        -- Champs agrégats (SUM, COUNT etc)
    FROM tables
    GROUP BY 
        case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end, 
        champ2
) T
ORDER BY case alias1 when 'tutu' then 1 when 'titi' then 2 when 'tutu' then 3 else 4 end, champ2

Bizarre hmm

Hors ligne

#6 24/07/2014 22:35:16

gleu
Administrateur

Re : Problème de ORDER BY sur un champ de type case when

Normalement on a le droit d'utiliser les alias dans ORDER BY.

Faux, pas avec PostgreSQL en tout cas.

Pour le moment, le seul moyen que j'ai trouvé de rendre l'exemple ci-dessus opérationnel, c'est de passer par une sous-requête

Et c'est en effet le seul moyen. Vous pouvez aussi passer par une requête CTE mais c'est plus ou moins la même chose en fait :

WITH t AS (SELECT
        case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end as alias1,
        champ2,
        -- Champs agrégats (SUM, COUNT etc)
    FROM tables
    GROUP BY 
        case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end, 
        champ2
)
SELECT * FROM t
ORDER BY case alias1 when 'tutu' then 1 when 'titi' then 2 when 'tutu' then 3 else 4 end, champ2

Il y a aussi cette solution :

SELECT
        case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end as alias1,
        champ2,
        -- Champs agrégats (SUM, COUNT etc)
    FROM tables
    GROUP BY 
        case when champ1 in ('toto', 'titi', 'tutu') then champ1 else 'tata' end, 
        champ2
ORDER BY case champ1 when 'tutu' then 1 when 'titi' then 2 when 'tutu' then 3 else 4 end, champ2

Quoique l'agrégat ne me permet pas d'être catégorique.


Guillaume.

Hors ligne

Pied de page des forums