Page 1 sur 1

SUM, une jointure qui pose problème ^^

Posté : 24 août 2015, 14:24
par foetus69
Bonjour,

Pouvez-vous m'aider sur ce problème svp merci ?

J'ai une table écoliers et une table absences. Je voudrais calculer pour chaque enfant son temps d'absence (c'est un exercice je ne fait pas de délation :D)

Y compris pour les enfants qui n'ont pas eu d'absences et c'est d'ailleurs eux qui me posent problème avec leur assiduité !!! :lol:

J'arrive pas à afficher Mattéo a été absent : 0 jours
SELECT *, SUM(nb_jours) AS total_jours
FROM
(
	SELECT *,
		CASE
			WHEN absences.fin = '0000-00-00' OR absences.fin IS NULL THEN DATEDIFF(CURRENT_DATE, absences.debut)
			ELSE DATEDIFF(absences.fin, absences.debut)
		END AS nb_jours
	FROM absences, ecoliers
) tmp
GROUP BY ecoliers.prenom

Féfé

Re: SUM, une jointure qui pose problème ^^

Posté : 24 août 2015, 17:35
par yann18
bonjour,
Est-ce que t'as vraiment besoin de stocker la fin d'une absence dans la table des absences au point de se retrouver avec des dates vides(0000-00-00, NULL)? logiquement la table des absences ne devraient contenir que les données (id, date absence) des écoliers absents, ainsi les écoliers qui n'y figurent pas dans cette table sont considérés de facto comme ceux n'ayant aucune absence.
Avec le MCD suivant

Code : Tout sélectionner

ecoliers(id,nom, prenom) absences(ecolier_fk, date_absence) ;//où ecolier_fk est la clé étrangère
Pour compter le nombre d'absences de chaque écolier, on fait une jointure à gauche(cf Jointures externes)

Code : Tout sélectionner

SELECT id, nom, prenom, COUNT(a.ecolier_fk) nb_absences FROM ecoliers LEFT JOIN absence a ON e.id=a.ecolier_fk GROUP BY id, nom, prenom

Re: SUM, une jointure qui pose problème ^^

Posté : 24 août 2015, 17:49
par Vince32

Code : Tout sélectionner

SELECT id, nom, prenom, COUNT(a.ecolier_fk) nb_absences FROM ecoliers LEFT JOIN absence a ON e.id=a.ecolier_fk GROUP BY id, nom, prenom
je pense que cette solution est la bonne. Il faut éviter de faire des requête compliquées avec MYSQL. Cela coûute moins cher en resource de faire plusieurs requêtes simples que une seule requête compliquée. :wink:

Re: SUM, une jointure qui pose problème ^^

Posté : 24 août 2015, 21:09
par foetus69
Bonsoir,

Merci de votre aide.

Euh non ça va pas aller. Je cherche à savoir le nombre de jours où les élèves ont été absents d'où le calcul et les dates de début et fin.

Car si quelqu'un est absent 10 x 1 journée ça ne fait que 10 jours alors qu'une fois 1 mais tout le mois d'août ça fera 31.

Fée

Re: SUM, une jointure qui pose problème ^^

Posté : 25 août 2015, 10:56
par yann18
Car si quelqu'un est absent 10 x 1 journée ça ne fait que 10 jours alors qu'une fois 1 mais tout le mois d'août ça fera 31.
ton groupement n'est probablement pas correct c-a-d les dates début et fin n'apparaissent pas dans la clause GROUP BY ce qui expliquerait qu'une absence du mois d'août soit compté 31 fois.

peux-tu poster la structure des tables ainsi qu'un jeu d'enregistrement?

Re: SUM, une jointure qui pose problème ^^

Posté : 25 août 2015, 11:43
par foetus69
Hola senor :)

Les tables ecoliers et absences :

Code : Tout sélectionner

CREATE TABLE IF NOT EXISTS `absences` ( `id` int(5) NOT NULL AUTO_INCREMENT, `qui` int(5) NOT NULL, `debut` date NOT NULL, `fin` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; INSERT INTO `absences` (`id`, `qui`, `debut`, `fin`) VALUES (1, 1, '2015-08-02', '2015-08-04'), (2, 2, '2015-05-10', '2015-05-16'), (3, 1, '2015-01-01', '2015-01-02');

Code : Tout sélectionner

CREATE TABLE IF NOT EXISTS `ecoliers` ( `idd` int(5) NOT NULL AUTO_INCREMENT, `prenom` varchar(5) NOT NULL, PRIMARY KEY (`idd`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; INSERT INTO `ecoliers` (`idd`, `prenom`) VALUES (1, 'eva'), (2, 'aline'), (3, 'mateo');
Le résultat que je cherche à afficher :
eva a été absent(e) 3 jours (2+1 somme des lignes 1 et 3 dans absences)
aline a été absent(e) 6 jours (ligne 2 dans absences)
mateo a été absent(e) 0 jours (car pas présent dans la table des absences)

En espérant être plus claire ^^

Re: SUM, une jointure qui pose problème ^^

Posté : 25 août 2015, 13:24
par yann18

Code : Tout sélectionner

SELECT idd, prenom,SUM(IFNULL(DATEDIFF(fin,debut),0)) nb_absences,debut,fin FROM ecoliers e LEFT JOIN absences a ON e.idd = a.qui GROUP BY idd, prenom,debut,fin;

Re: SUM, une jointure qui pose problème ^^

Posté : 25 août 2015, 14:29
par foetus69
Kikoo Yann,

C'était super jusqu'à ce que j'ajoute une absence pour eva, ça me recrée une ligne avec le prénom plutôt que de faire la somme des lignes pour le même écolier ^^
J'ai essayé de rajouter "qui" dans le select et le group by mais ça ne change rien :(

Féfé

Re: SUM, une jointure qui pose problème ^^

Posté : 25 août 2015, 15:45
par yann18
il suffit d'enlever la date début et la date fin dans le regroupement ainsi que dans le SELECT pour ressortir qu'une seule ligne par écolier:

Code : Tout sélectionner

SELECT idd, prenom,SUM(IFNULL(DATEDIFF(fin,debut),0)) nb_absences FROM ecoliers e LEFT JOIN absences a ON e.idd = a.qui GROUP BY idd, prenom;
toutefois si tu souhaites que les dates d'absences figurent dans le résultat sans pour autant en créer une nouvelle ligne d'un écolier tu peux utiliser la fonction mysql GROUP_CONCAT() qui permet de regrouper, en une seule ligne, les dates d'absences (début et fin) d'un écolier.

Code : Tout sélectionner

SELECT idd, prenom,SUM(IFNULL(DATEDIFF(fin,debut),0)) nb_absences,GROUP_CONCAT(CONCAT(debut,'/', fin )) periodes FROM ecoliers e LEFT JOIN absences a ON e.idd = a.qui GROUP BY idd, prenom;
où période représente le couple(date debut,date fin).chaque couple étant séparé par des virgules

Re: SUM, une jointure qui pose problème ^^

Posté : 26 août 2015, 12:08
par foetus69
Kikoo,

C'est tout bon !!!!

:pouce: