Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 28/10/2011, 09h33   #1
Expert Confirmé
 
Avatar de grunk
 
Homme Olivier
Développeur Web
Inscription : août 2003
Messages : 1 837
Détails du profil
Informations personnelles :
Nom : Homme Olivier
Âge : 27
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Industrie

Informations forums :
Inscription : août 2003
Messages : 1 837
Points : 3 318
Points : 3 318
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 :
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 :
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 :
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 :
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
grunk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 11h55   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Essaie ceci :
Code :
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 13h54   #3
Expert Confirmé
 
Avatar de grunk
 
Homme Olivier
Développeur Web
Inscription : août 2003
Messages : 1 837
Détails du profil
Informations personnelles :
Nom : Homme Olivier
Âge : 27
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Industrie

Informations forums :
Inscription : août 2003
Messages : 1 837
Points : 3 318
Points : 3 318
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 :
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 ...
grunk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/11/2011, 15h57   #4
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
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 :
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.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 02/11/2011, 17h06   #5
Expert Confirmé
 
Avatar de grunk
 
Homme Olivier
Développeur Web
Inscription : août 2003
Messages : 1 837
Détails du profil
Informations personnelles :
Nom : Homme Olivier
Âge : 27
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Industrie

Informations forums :
Inscription : août 2003
Messages : 1 837
Points : 3 318
Points : 3 318
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.
grunk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h04.


 
 
 
 
Partenaires

Hébergement Web