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 MySQL Discussion :

SUM sur deux tables


Sujet :

Requêtes MySQL

  1. #1
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut SUM sur deux tables
    Bonjour à tous,

    J'essai de faire la somme de deux champs (se trouvant sur deux tables) pour un même utilisateurs.
    J'ai la structure suivante :

    Une table "users" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    +--------------+------------------+------+-----+---------+----------------+
    | Field        | Type             | Null | Key | Default | Extra          |
    +--------------+------------------+------+-----+---------+----------------+
    | id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | nom          | varchar(100)     | NO   |     | NULL    |                |
    | prenom       | varchar(100)     | NO   |     | NULL    |                |
    +--------------+------------------+------+-----+---------+----------------+
    Une table "taches" , contenant des taches à effectuer. Une tache est associé à un utilisateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    +-------------+----------------------+------+-----+---------+----------------+
    | Field       | Type                 | Null | Key | Default | Extra          |
    +-------------+----------------------+------+-----+---------+----------------+
    | id          | int(10) unsigned     | NO   | PRI | NULL    | auto_increment |
    | idUser      | int(10) unsigned     | NO   | MUL | NULL    |                |
    | titre       | varchar(255)         | NO   |     | NULL    |                |
    | occupation  | int(11)              | NO   |     | 0       |                |
    +-------------+----------------------+------+-----+---------+----------------+
    Une table taches_users qui permet d'associer des utilisateurs "secondaire" à une tache.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    +------------+------------------+------+-----+---------+----------------+
    | Field      | Type             | Null | Key | Default | Extra          |
    +------------+------------------+------+-----+---------+----------------+
    | id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | idUser     | int(10) unsigned | NO   | MUL | NULL    |                |
    | idTache    | int(10) unsigned | NO   | MUL | NULL    |                |
    | occupation | int(11)          | NO   |     | 0       |                |
    +------------+------------------+------+-----+---------+----------------+
    J'arrive évidemment à récupérer le total d'occupation par utilisateur pour les taches :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT
        SUM(t.occupation),
        u.prenom,u.nom
    FROM taches t
        INNER JOIN users u ON u.id = t.idUser
        GROUP BY u.id
    Un utilisateur étant soit directement attaché à une tache soit utilisateur secondaire d'une tache (via la table taches_users) j'aimerais arriver à faire le total de son occupation (en gros faire un SUM général de "occupation" quelque soit la table).
    Le but final étant d'obtenir la liste des utilisateurs avec leur occupations totale.
    Est ce possible avec une seule requête ou dois je forcément passer par deux petite requêtes comme celle présentée précedemment ?

    Note : j'ai pas la main sur la structure de la table qui ne me semble pas idéale.

    Merci
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  2. #2
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Essaie ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT u.id, u.prenom, u.nom, 
    	SUM(COALESCE(t.occupation, 0) + SUM(COALESCE(tu.occupation, 0)) AS somme_occupation
    FROM users u
    LEFT OUTER JOIN taches t ON u.id = t.idUser
    LEFT OUTER JOIN taches_users tu ON tu.idUser = u.id
    GROUP BY u.id, u.prenom, u.nom
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

  3. #3
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Merci de ta réponse.
    j'étais arriver à quelque chose de similaire (sans les COALESCE inutile dans mion cas et avec des jointure un peu différente) mais ta requête à le même problème que celle que j'avais fait , c'est à dire que les résultats ne sont pas correcte.

    Tout va bien tant qu'un utilisateur n'as pas de données dans taches et taches_users. Quand il à des données dans les deux les calculs ne sont plus bon.
    je n'arrive pas à trouver de logique dans les résultats calculer.
    Par exemple avec ces données :

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    --
    -- Structure de la table `taches`
    --
     
    CREATE TABLE IF NOT EXISTS `taches` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `idUser` int(11) NOT NULL,
      `titre` varchar(50) NOT NULL,
      `occupation` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
     
    --
    -- Contenu de la table `taches`
    --
     
    INSERT INTO `taches` (`id`, `idUser`, `titre`, `occupation`) VALUES
    (1, 1, 'Tache 1', 10),
    (2, 2, 'Tache 2', 5),
    (3, 1, 'Tache 3', 2),
    (4, 1, 'Tache 4', 12);
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `taches_users`
    --
     
    CREATE TABLE IF NOT EXISTS `taches_users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `idUser` int(11) NOT NULL,
      `idTache` int(11) NOT NULL,
      `occupation` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
     
    --
    -- Contenu de la table `taches_users`
    --
     
    INSERT INTO `taches_users` (`id`, `idUser`, `idTache`, `occupation`) VALUES
    (1, 2, 1, 25),
    (2, 2, 4, 7),
    (3, 1, 2, 24);
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `users`
    --
     
    CREATE TABLE IF NOT EXISTS `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `nom` varchar(50) NOT NULL,
      `prenom` varchar(50) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
     
    --
    -- Contenu de la table `users`
    --
     
    INSERT INTO `users` (`id`, `nom`, `prenom`) VALUES
    (1, 'Dupont', 'Jean'),
    (2, 'Tournesol', 'Triffon'),
    (3, 'arien', 'glandeur');
    J'obtient pour Dupont 96 au lieu de 48 (10 +2 +12 +24) et pour Tournesol 42 au lieu de 37 (5 + 25 +7). y'a sans doute quelques chose qui est compté plusieurs fois mais quoi ...
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 954
    Par défaut
    Retire les SUM et le GROUP BY, tu verras que :
    24 + 24 + 24 + 10 + 2 + 12 = 96
    5 + 5 + 27 + 7 = 42

    Essaie comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT u.id, u.prenom, u.nom, 
           COALESCE(t.sum_tache,0) + COALESCE(tu.sum_tache_usr,0) AS somme_occupation
    FROM users u
    LEFT OUTER JOIN (select idUser, SUM(occupation) as sum_tache
                       from taches 
                      group by idUser
                    ) t ON u.id = t.idUser
    LEFT OUTER JOIN (select idUser, SUM(occupation) as sum_tache
                       from taches_users
                      group by idUser
                    ) tu ON tu.idUser = u.id
    PS : le coalesce sert pour l'opérateur + qui n'est pas NULL compatible, il est indispensable si un user peut avoir des occupations dans seulement 1 des 2 tables.

  5. #5
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Merci pour ta réponse , ca marche !

    Pour le coalesce je n'avais effectivement pas penser au fait qu'un utilisateur peut ne pas être présent partout.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Sum de deux champs sur deux tables différentes
    Par kluh dans le forum Oracle
    Réponses: 11
    Dernier message: 29/09/2005, 18h21
  2. Cumul sur deux tables
    Par lper dans le forum Langage SQL
    Réponses: 6
    Dernier message: 30/11/2004, 15h02
  3. Comptez sur deux tables en même temps
    Par genova dans le forum Langage SQL
    Réponses: 12
    Dernier message: 13/09/2004, 18h58
  4. trigger sur deux tables
    Par Shabata dans le forum Développement
    Réponses: 4
    Dernier message: 04/05/2004, 16h55
  5. 2 Count() sur deux tables en jointures gauches
    Par Alexandre T dans le forum Langage SQL
    Réponses: 2
    Dernier message: 03/09/2003, 16h53

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