Requête particulière, comment faire ?

Bonjour à tous,

Voilà je vais essayer de vous expliquer mon petit cas de figure sur lequel je me prends la tête. Je travaille sur une petite application qui permet de gérer des pointages.

J’ai deux tables regroupant un certains nombre de champs dont ceux présentés ci-dessous :

Pointage
Id_pointage | id_user | semaine | temps | …

Users
Id_user | nom | prenom | …

Mon souhait est de faire une requête qui me ressorte toutes les personnes n’ayant pas pointé 5 jours (temps) / semaine et ce pour toutes les semaines passées, avec un résultat sous la forme suivante :

Id_user | semaine | temps

J’ai donc crée la requête suivante :

SELECT semaine,id_user,SUM(temps) AS totalJ FROM pointage WHERE semaine<42
GROUP BY id_user,semaine HAVING totalJ<5 ORDER BY id_user

Le hic avec cette requête, c’est que seules les lignes des personnes ayant effectué au moins un pointage pour une semaine donnée apparaissent.

Si par exemple l’id_user 1 n’a effectué aucun pointage pour la semaine 40, il n’apparaitra pas. Un peu embêtant pour une requête devant me donner toutes les personnes en retard de pointage. Par contre si il avait juste pointé 1 jour, il serait apparu.

Alors j’ai essayé de modifier ma requête dans tous les sens, en créant une table semaine, en faisant de LEFT / RIGHT JOIN mais rien n’y fait, je ne m’en sors pas !

Avez-vous une idée de comment je peux construire cette « foutu » requête !?

Par avance grand merci pour votre aide.

A vue de nez, et en utilisant une table Semaine, je dirais quelque chose comme ça : (pas essayé)

SELECT p.semaine, u.id_user, SUM(p.temps) AS totalJ
FROM Users u, Semaine s
LEFT JOIN Pointage p ON p.Semaine = s.Semaine
WHERE p.semaine < 42
GROUP BY u.id_user,s.semaine HAVING p.totalJ<5 
ORDER BY u.id_user

Le raisonnement :

Tu commences par obtenir le produit cartésien des users et des semaines :
SELECT * FROM Users u, Semaine s

Sauf erreur de ma part, tu obtiens avec cette requête une ligne pour chaque semaine, et ce pour tous les utilisateurs.

A partir de là, tu n’as plus qu’à croiser avec la table de pointage, avec un LEFT JOIN pour gérer les cas où aucune information de pointage n’est présente. J’ai quelques doutes sur la syntaxe par contre.

Merci pour votre aide. Je ne suis pas loin du but en utilisant votre idée mais ça bloque au niveau du “SUM”.

En faites j’arrive bien à avoir un résultat sous forme id_user / semaine. Par contre mon “SUM” me fait la somme de tous les pointages de la personnes. Du coup mon résultat se présente de la manière suivante : id_user : 1 / semaine : 40 / totalJ : 225, alors que pour une semaine complète j’aurais aimé un résultat sous cette forme : id_user : 1 / semaine : 40 / totalJ : 5

Avez vous une idée de comment je peux résoudre ce dernier point !

Voici le code que j’ai utilisé :

SELECT T1.id_semaine AS semaine,T1.id_user, SUM(temps) AS totalJ
FROM pointage p
RIGHT JOIN
(
    SELECT
        u.id_user,s.id_semaine
    FROM utilisateur u,semaine s
    WHERE id_semaine <= 42
    GROUP BY id_user,id_semaine
) T1
ON p.id_user = T1.id_user
WHERE T1.id_user=55
GROUP BY T1.id_semaine, T1.id_user
ORDER BY semaine