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 27/01/2011 12:03:50

meles
Membre

Réutilisation d'un alias au sein d'un même requête

Bonjour,
  mon problème du jour est le suivant, je souhaiterai réutiliser dans une même requête un alias de colonne (dans mes souvenir oraclien, c'était faisable) mais là, je n'y arrive pas;

Au lieu d'écrire ça:
select extract(isodow from '2011-01-11'::date) as joursem, case when extract(isodow from '2011-01-11'::date) > 5 then 700 else 500 end;
je voudrais pouvoir écrire ça
select extract(isodow from '2011-01-11'::date) as joursem, case when joursem > 5 then 700 else 500 end;

C'est également valable pour les "order" sur des alias de colonnes ou des "having".

Cordialement

Hors ligne

#2 27/01/2011 12:09:37

Marc Cousin
Membre

Re : Réutilisation d'un alias au sein d'un même requête

Non, on ne peut pas…

Un mail de Tom Lane qui l'explique : http://archives.postgresql.org/pgsql-ge … g01411.php

La clause WHERE est évaluée avant la liste SELECT. C'est peut-être géré par Oracle (je ne me souviens plus), mais c'est impossible tel quel sous Postgres. On peut le faire avec une sous-requête si c'est vraiment vital.


Marc.

Hors ligne

#3 27/01/2011 12:19:30

Marc Cousin
Membre

Re : Réutilisation d'un alias au sein d'un même requête

J'ai un peu farfouillé sur le net: Ni Oracle, ni SQL Server n'acceptent cela non plus.

Apparemment, ça passe avec MySQL par contre.


Marc.

Hors ligne

#4 27/01/2011 12:38:41

meles
Membre

Re : Réutilisation d'un alias au sein d'un même requête

Oui, je viens d'aller voire la réponse de Tom, et je comprend bien que dans le cas qui etait posé, il ne puisse evaluer le résultat du select avant le where, sauf qu'en l'occurence, mes alias de colonnes ne sont pas dans la clause WHERE, mais dans la partie SELECT.

De la même manière, sur un ORDER BY ou un HAVING, on peut s'attendre à ce que ces clauses soient évaluées après le SELECT et partant de là, utiliser leurs alias (on  y arrive bien avec un ORDER BY 1 (1 n'est t'il pas un alias de la première colonne ?)).

Au delà de la flemme d'écrire deux fois un "case" complexe (pas celui de l'exemple, hein), je voulais éviter de lui faire faire deux fois les calculs (et puis ça amèliore la lisibilité du code, quand on en modofie un, on est pas obliger d'aller faire la même chose sur l'autre, etc ...).

Après test avec une sous requête (comme proposé par Tom), je gagne presque rien!

Sur ma vraie requête, voila le résultat du subselect:

Sort  (cost=29.89..30.39 rows=200 width=68) (actual time=22869.369..22869.441 rows=365 loops=1)
  Sort Key: ss.ddj, ss.nbplaces
  Sort Method:  quicksort  Memory: 42kB
  ->  Subquery Scan on ss  (cost=15.25..22.25 rows=200 width=68) (actual time=22868.321..22869.102 rows=365 loops=1)
        ->  HashAggregate  (cost=15.25..19.25 rows=200 width=36) (actual time=22868.315..22868.669 rows=365 loops=1)
              ->  Function Scan on nb_present  (cost=0.25..10.25 rows=1000 width=36) (actual time=22850.656..22855.744 rows=17155 loops=1)
Total runtime: 22873.190 ms

et celui ou on réécrit deux fois les fonctions:

Sort  (cost=32.39..32.89 rows=200 width=36) (actual time=22941.980..22942.053 rows=365 loops=1)
  Sort Key: ddj, (CASE WHEN (date_part('isodow'::text, (ddj)::timestamp without time zone) > 5::double precision) THEN 705.0 ELSE 748.0 END)
  Sort Method:  quicksort  Memory: 42kB
  ->  HashAggregate  (cost=17.75..24.75 rows=200 width=36) (actual time=22940.959..22941.712 rows=365 loops=1)
        ->  Function Scan on nb_present  (cost=0.25..10.25 rows=1000 width=36) (actual time=22923.321..22928.387 rows=17155 loops=1)
Total runtime: 22945.881 ms

Au delà du gain en performance pure, ne peut on pas imaginer que le developpemnt d'un telle fonctionalité serait un plus dans la facilité d'utilisation?

Cordialement

Hors ligne

#5 27/01/2011 12:50:51

Marc Cousin
Membre

Re : Réutilisation d'un alias au sein d'un même requête

Le subselect n'est pas là pour gagner du temps, même si on peut avoir de petits gains dans certains cas. Il est donné dans l'exemple comme façon de réécrire la requête avec des alias de colonnes.

Pour ce qui est des alias, à mon avis, si ça n'y est dans aucun des 3 moteurs, c'est que ce n'est pas dans la norme SQL (mais je ne suis pas allé vérifier smile ). Sinon ça aurait été rajouté.

En tout cas, ce forum, ce n'est pas le bon endroit pour demander des nouvelles fonctionnalités smile


Marc.

Hors ligne

#6 27/01/2011 13:03:08

meles
Membre

Re : Réutilisation d'un alias au sein d'un même requête

Marc Cousin a écrit :

En tout cas, ce forum, ce n'est pas le bon endroit pour demander des nouvelles fonctionnalités smile

J'avais bien noté wink

Pour le subselect, certes il n'est pas la pour faire gagner du temps, mais le fait de ne pas avoir à écrire deux fois (et donc à calculer) certaines fonctions ou conditions aurait pu améliorer les choses.

Manifestement, c'est raté!

Cordialement

Hors ligne

#7 27/01/2011 14:09:55

Marc Cousin
Membre

Re : Réutilisation d'un alias au sein d'un même requête

Ça peut, dans certains cas, effectivement, améliorer les temps d'exécution. Il y a d'autres cas où ça peut les ralentir, si par exemple certains prédicats de clauses where ne peuvent plus être poussés dans la sous-requête.


Marc.

Hors ligne

Pied de page des forums