IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Comment eviter la creation d'une table temporaire


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut Comment eviter la creation d'une table temporaire
    Bonjour

    je voudrais eviter de passer par une table temporaire, mais je ne trouve pas de solution valable.
    Voici ma premiere requete avec laquelle je construit ma table temporaire que je nomme stat_quotidienne022010
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    SELECT ssj.date as date_serv_jour,
    saj.nb_serveurs as nb_serv_app_jour,
    sum(ssj.obj_sauve) as val_obj_sauve_jour,
    sum(ssj.vol_sauve) as val_vol_sauve_jour,
    sum(ssj.nb_sauve) as val_nb_sauve_jour,
    sum(ssj.err_sauve) as val_err_sauve_jour,
    sum(ssj.obj_rest) as val_obj_rest_jour,
    sum(ssj.vol_rest) as val_vol_rest_jour,
    sum(ssj.nb_rest) as val_nb_rest_jour,
    sum(ssj.err_rest) as val_err_rest_jour,
    a.appli
    FROM stat_serveur_jour ssj
    LEFT OUTER JOIN serveurs s on ssj.id_serv=s.id_serv
    LEFT OUTER JOIN applis a on s.id_app=a.id_app
    LEFT OUTER JOIN groupe_app ga on a.id_app=ga.id_app
    LEFT OUTER JOIN domaines d on ga.id_dom=d.id_dom
    LEFT OUTER JOIN stat_app_jour saj on s.id_app=saj.id_app
    WHERE ssj.date=saj.date
    AND date_part('month',ssj.date)='02' 
    AND date_part('year',ssj.date)='2010' 
    AND d.domaine='Mon_domaine'
    GROUP BY ssj.date,saj.nb_serveurs,appli 
    ORDER BY ssj.date,saj.nb_serveurs,appli
    ;
    Ensuite à partie de cette table, je l'attaque avec cette nouvelle requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select date_serv_jour,sum(nb_serv_app_jour),sum(val_obj_sauve_jour),
    sum(val_vol_sauve_jour),sum(val_nb_sauve_jour),sum(val_err_sauve_jour) 
    sum(val_obj_rest_jour),sum(val_vol_rest_jour),sum(val_nb_rest_jour)
    sum(val_err_rest_jour)
    from stat_quotidienne022010
    group by date_serv_jour
    order by date_serv_jour;
    D'avance merci pour vos suggestions
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    En une seule requête indentées avec une CTE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    WITH 
    T1 AS
    (
    SELECT ssj.date as date_serv_jour,
           saj.nb_serveurs as nb_serv_app_jour,
           sum(ssj.obj_sauve) as val_obj_sauve_jour,
           sum(ssj.vol_sauve) as val_vol_sauve_jour,
           sum(ssj.nb_sauve) as val_nb_sauve_jour,
           sum(ssj.err_sauve) as val_err_sauve_jour,
           sum(ssj.obj_rest) as val_obj_rest_jour,
           sum(ssj.vol_rest) as val_vol_rest_jour,
           sum(ssj.nb_rest) as val_nb_rest_jour,
           sum(ssj.err_rest) as val_err_rest_jour,
           a.appli
    FROM   stat_serveur_jour ssj
           LEFT OUTER JOIN serveurs s 
                on ssj.id_serv=s.id_serv
           LEFT OUTER JOIN applis a 
                on s.id_app=a.id_app
           LEFT OUTER JOIN groupe_app ga 
                on a.id_app=ga.id_app
           LEFT OUTER JOIN domaines d 
                on ga.id_dom=d.id_dom
           LEFT OUTER JOIN stat_app_jour saj 
                on s.id_app=saj.id_app
    WHERE  ssj.date=saj.date
      AND  date_part('month',ssj.date)='02'  
      AND  date_part('year',ssj.date)='2010'
      AND  d.domaine='Mon_domaine'
    GROUP  BY ssj.date,saj.nb_serveurs,appli
    )
    SELECT date_serv_jour,sum(nb_serv_app_jour),sum(val_obj_sauve_jour),
           sum(val_vol_sauve_jour),sum(val_nb_sauve_jour),sum(val_err_sauve_jour)
           sum(val_obj_rest_jour),sum(val_vol_rest_jour),sum(val_nb_rest_jour)
           sum(val_err_rest_jour)
    from   T1
    group  by date_serv_jour
    order  by date_serv_jour;
    Lisez l'article que j'ai écrit sur la CTE : http://sqlpro.developpez.com/cours/s...te-recursives/
    Si votre version ne supporte pas les CTE faire de la première requête une vue.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 135
    Points : 164
    Points
    164
    Par défaut
    de cette façon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    select date_serv_jour,sum(nb_serv_app_jour),sum(val_obj_sauve_jour),
    sum(val_vol_sauve_jour),sum(val_nb_sauve_jour),sum(val_err_sauve_jour) 
    sum(val_obj_rest_jour),sum(val_vol_rest_jour),sum(val_nb_rest_jour)
    sum(val_err_rest_jour)
    from (SELECT ssj.date as date_serv_jour,
                      saj.nb_serveurs as nb_serv_app_jour, 
                       sum(ssj.obj_sauve) as val_obj_sauve_jour,
                       sum(ssj.vol_sauve) as val_vol_sauve_jour,
                      sum(ssj.nb_sauve) as val_nb_sauve_jour,
                     sum(ssj.err_sauve) as val_err_sauve_jour,
                      sum(ssj.obj_rest) as val_obj_rest_jour,
                    sum(ssj.vol_rest) as val_vol_rest_jour,
                     sum(ssj.nb_rest) as val_nb_rest_jour,
                    sum(ssj.err_rest) as val_err_rest_jour,
                    a.appli
            FROM stat_serveur_jour ssj
            LEFT OUTER JOIN serveurs s on ssj.id_serv=s.id_serv
            LEFT OUTER JOIN applis a on s.id_app=a.id_app
            LEFT OUTER JOIN groupe_app ga on a.id_app=ga.id_app
           LEFT OUTER JOIN domaines d on ga.id_dom=d.id_dom
           LEFT OUTER JOIN stat_app_jour saj on s.id_app=saj.id_app
           WHERE ssj.date=saj.date
           AND date_part('month',ssj.date)='02' 
           AND date_part('year',ssj.date)='2010' 
           AND d.domaine='Mon_domaine'
           GROUP BY ssj.date,saj.nb_serveurs,appli 
          ORDER BY ssj.date,saj.nb_serveurs,appli
         )  as TB 
    group by date_serv_jour
    order by date_serv_jour;

  4. #4
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Merci à SQLpro
    Mais la version de postgres 7.4.13
    ne reconnait pas le mot WITH
    Sinon, je vais regarder pour la creation d'une vue.

    Merci à Teach pour la reponse,car elle fonctionne correctement.
    Seul inconvenient, le temps d'execution.
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  5. #5
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    La suite de mes tergiversations
    Voici le script de création de la vue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CREATE VIEW vstat_quotidienne_jour AS (
    SELECT ssj.date AS date_serv_jour,
    saj.nb_serveurs AS nb_serv_app_jour, 
    sum(ssj.obj_sauve) AS val_obj_sauve_jour,
    sum(ssj.vol_sauve) AS val_vol_sauve_jour,
    sum(ssj.nb_sauve) AS val_nb_sauve_jour,
    sum(ssj.err_sauve) AS val_err_sauve_jour,
    sum(ssj.obj_rest) AS val_obj_rest_jour,
    sum(ssj.vol_rest) AS val_vol_rest_jour,
    sum(ssj.nb_rest) AS val_nb_rest_jour,
    sum(ssj.err_rest) AS val_err_rest_jour,
    a.appli,d.domaine
    FROM stat_serveur_jour ssj
    LEFT OUTER JOIN serveurs s ON ssj.id_serv=s.id_serv
    LEFT OUTER JOIN applis a ON s.id_app=a.id_app
    LEFT OUTER JOIN groupe_app ga ON a.id_app=ga.id_app
    LEFT OUTER JOIN domaines d ON ga.id_dom=d.id_dom
    LEFT OUTER JOIN stat_app_jour saj ON s.id_app=saj.id_app
    WHERE ssj.date=saj.date
    GROUP BY ssj.date,saj.nb_serveurs,appli,d.domaine 
    ORDER BY ssj.date,saj.nb_serveurs,appli
    );
    J'ai rajouté la colonne domaine car j'en ai besoin dans la requete suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select date_serv_jour,sum(nb_serv_app_jour),sum(val_obj_sauve_jour),
    sum(val_vol_sauve_jour),sum(val_nb_sauve_jour),sum(val_err_sauve_jour), 
    sum(val_obj_rest_jour),sum(val_vol_rest_jour),sum(val_nb_rest_jour),
    sum(val_err_rest_jour)
    from vstat_quotidienne_jour
    WHERE date_part('month',date_serv_jour)='mois_choisi'
    AND date_part('year',date_serv_jour)='annee_choisie'
    AND domaine='Domaine_choisi'
    group by date_serv_jour
    order by date_serv_jour;
    Cela fonctionne mais il faut compter une vingtaine de seconde pour avoir la reponse
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    En ce qui concerne les performances, il faut savoir que ce type de clause:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE date_part('month',date_serv_jour)='mois_choisi'
    AND date_part('year',date_serv_jour)='annee_choisie'
    devrait être remplacé par ce type d'expression:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE date_serv_jour>=to_date(:param, 'DD/MM/YYYY') 
    AND date_serv_jour<to_date(:param, 'DD/MM/YYYY')+ '1 month'::interval
    en passant dans :param une valeur du genre 01/03/2010 où 03 et 2010 sont bien sûr le mois et l'année choisis.
    L'intérêt est que l'optimiseur étant capable de se rendre compte que les dates en question sont constantes pendant l'exécution de la requête, dans le cas où date_serv_jour est indexé, il peut éviter de lire toute la table en utilisant cet index.

  7. #7
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Merci pour la réponse Estofilo
    Mais je ne vois pas comment faire pour utiliser ta requête, sachant que celle-ci est lancé à partir d'une interface Web (écrit en perl). Je récupère en paramètre le mois et l'année, et je remplace les variables $mois_choisi et $annee_choisi. Donc, comment faire pour transposer ma requête de la façon que tu indiques?
    Là, je sèche ???
    D'avance merci
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Mais je ne vois pas comment faire pour utiliser ta requête, sachant que celle-ci est lancé à partir d'une interface Web (écrit en perl). Je récupère en paramètre le mois et l'année, et je remplace les variables $mois_choisi et $annee_choisi. Donc, comment faire pour transposer ma requête de la façon que tu indiques?
    Tu as donc par exemple 3 pour le mois et 2010 pour l'année. A partir de ces deux variables, tu ne peux pas construire la chaine "01/03/2010" et la passer à la requête?

  9. #9
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Si je récupère bien le mois et l'année mais je ne récupère pas le jour.
    Car le but étant d'afficher des statistiques sur le mois complet.
    Donc, le dernier mois calculé 02 année 2010.
    D'avance merci
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Si je récupère bien le mois et l'année mais je ne récupère pas le jour.
    Le jour c'est 1, pour le 1er jour du mois.
    Pour couvrir tous les jours d'un mois avec un champ date, on l'exprime en disant que ce sont tous les jours compris entre le 1er jour compris du mois en question et le 1er jour non compris du mois suivant. C'est ce qu'exprime le bout de requête que j'ai posté.

  11. #11
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Ok, merci.
    C'est tout bon. J'ai enfin percuté, comme on dit j'ai le cerveau lent ce jour
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Un BETWEEN serait peut-être encore plus optimum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    date_serv_jour BETWEEN '2010-02-01' AND '2010-02-28'
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  13. #13
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Novembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 319
    Points : 144
    Points
    144
    Par défaut
    Bonjour
    merci Cinephil, mais dans mon cas je préfère la réponse de Estofilo car je n'ai pas besoin de savoir si le mois fait 28,29 30 ou 31 jours.
    Je ne dois renseigner que le mois et l'année et pour un traitement batch c'est plus simple.
    Si tu tapes ta tête contre une cruche et que ça sonne creux,n'en déduis pas que c'est la cruche qui est vide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/10/2010, 23h53
  2. creation d'une table temporaire
    Par dark_botsay dans le forum ASP.NET
    Réponses: 10
    Dernier message: 04/08/2010, 14h10
  3. Réponses: 6
    Dernier message: 06/03/2008, 10h46
  4. [ASE 12.5.3][TSQL] - Creation d'une table temporaire en dynamique
    Par CVince dans le forum Adaptive Server Enterprise
    Réponses: 4
    Dernier message: 16/06/2006, 15h30
  5. Réponses: 4
    Dernier message: 16/06/2006, 15h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo