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

Langage SQL Discussion :

Est-il possible de recuperer une somme cumulative avec une fonction d'agrégats ?


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut Est-il possible de recuperer une somme cumulative avec une fonction d'agrégats ?
    Je m'explique :

    je souhaite récupérer, par exemple, le nombre total de produits créés par mois. Par total, j'entend le nombre de produits dans le mois additionné au total de tous les mois précédents.
    J'espérai qu'il soit possible de faire une somme (SUM(produits)) groupée par mois (GROUP BY dateprod) à laquelle j'additionnerais la somme du mois précédent.

    Seulement, je ne sais pas comment cela et si cela est possible...

    Si oui, je suis preneur de tout exemple ou toute doc que j'adapterai à mon cas.

    Bonne journée

  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 902
    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 902
    Points : 51 646
    Points
    51 646
    Billets dans le blog
    6
    Par défaut
    Oui en utilisant les fonctions de fenêtrage... Si votre SGBDR les supportent !

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select t1.region_name,
            t2.division_name,
            t3.month,
            tsum(t3.amount) AS TOTAL,
            sum(t3.amount) over (partition by t1.region_name, t2.division_name
                                 order     by t3.month rows unbounded preceding)  AS CUMUL
    from    region t1
            INNER JOIN sales t3
                  ON   t1.region_id=t3.region_id
            INNER JOIN division t2 
                  ON  t2.division_id=t3.division_id
    where   t3.year=2004
    A +

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Vous pouvez aussi faire le cumul avec une auto jointure.

    Imaginons la table :
    T_CAMOIS = {Annee, Mois, CA}

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT A.Annee, A.Mois, A.CA, Sum(B.Mois) as CA_CUMUL
    FROM T_CAMOIS A
    	INNER JOIN T_CAMOIS B
    		ON A.Annee = B.Annee AND A.Mois >= B.Mois
    GROUP BY A.Annee, A.Mois, A.CA
    La table prise en exemple utilise une année et un mois sous forme d'entier. Si votre table utilise un type date, il faudra utiliser les fonctions de gestion des dates afin d'extraire les informations souhaitées.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    Merci beaucoup pour ces infos précieuses

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut Ca ne semble pas fonctionner
    J'ai essayé et ça ne semble pas fonctionner. La requête ne se termine jamais.

    Voici ma table:
    [Produits]
    taille (double)
    dateprod (timestamp)

    La requete testée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT sum(A.taille) AS taille_cumul,
    date_part('year',A.dateprod) as annee
    FROM produits A
    INNER JOIN produits B
    ON date_part('year',A.dateprod) >= date_part('year',B.dateprod)
    GROUP BY annee
    J'ai fait différents essais en changeant l'operateur >=, >, = [...]-1, etc...
    Sans resultat concluant.

    Où me serai-je trompé ?

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Le fait que la requête ne se termine pas ne veut pas dire qu'elle ne fonctionne pas. Au contraire elle s'execute. Ensuite il est possible qu'elle ne retourne pas le résultat escompté c'est un autre problème.

    Essayez d'analyser le plan d'execution de la requête si ça vous est possible. Vous verrez si une optimisation est possible.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    Le fait que la requête ne se termine pas ne veut pas dire qu'elle ne fonctionne pas. Au contraire elle s'execute. Ensuite il est possible qu'elle ne retourne pas le résultat escompté c'est un autre problème.
    Effectivement. Mais je ne pense pas qu'elle fasse ce que je souhaite, ça ne peut pas être si long (il y a environ 20 000 enregistrements sur environ 5 années).

    Je pense qu'il y a une boucle très longue, voire sans fin dans cette requête, et vu le résultat que je veux, je sais que ça ne doit pas être si long (ça ne devrait pas prendre plus de quelques secondes en étant pessimiste), or ça dépasse la minute.

    Je vais regarder le plan mais j'avoue que ça ne me parle guère. Si quelqu'un a une idée, par rapport à ma requête et la structure de mes tables...

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Je pense qu'il est clair que PG ne peut utiliser d'index pour traiter là condition de jointure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    date_part('year',A.dateprod) >= date_part('year',B.dateprod)
    Je n'ai pas d'expérience sur PG mais je sais qu'il est possible de créer un index sur une fonction déterministe. Si votre date_part est déterministe, je pense que vous pouvez créer un index dont PG saura tirer profit.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    Je n'ai pas d'expérience sur PG mais je sais qu'il est possible de créer un index sur une fonction déterministe. Si votre date_part est déterministe, je pense que vous pouvez créer un index dont PG saura tirer profit.
    Ok, je vais donc demander sur un forum de pg. Pour moi, date_part() est effectivement déterministe.

    Merci pour vos réponses.

Discussions similaires

  1. Réponses: 8
    Dernier message: 10/02/2014, 14h57
  2. Afficher un cumul ou une somme dans un état
    Par Alex063 dans le forum Access
    Réponses: 4
    Dernier message: 07/02/2006, 15h37
  3. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24
  4. [W3C] Est-il possible d'afficher un div par dessus une applet ?
    Par drinkmilk dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 23/02/2005, 10h22
  5. Réponses: 7
    Dernier message: 08/03/2004, 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