Question MySQL - jointures externes

Répondre
InTheMix
le 02/07/2009 à 15:20
InTheMix
Hello,

Je m'essaie aux jointures externes depuis hier, de façon à simplifier mes requêtes. Simplifier dans le sens "ne faire qu'une requête" à la place dans faire plusieurs de suites.

Alors, j'expose un peu...

C'est une requête entre 5 tables.

users : table qui contient les noms des utilisateurs ainsi que l'id_group (qui correspond au groupe de la table groups)

opentask : table "lien" entre users et task

openpauses : table "lien" entre users et pauses

task : table qui contient les différentes tâches à effectuer

pauses : table qui contient les différentes pauses ( = horaires de travail du style 8h-15h, 15h-22h ...)

Pour l'instant, j'utilise la requête suivante :

SELECT u.id_users, u.name, u.surname, ot.id_task, op.id_pause, t.namefr, t.namenl, t.level, p.tag
FROM users u
LEFT OUTER JOIN opentask ot
ON u.id_users = ot.id_users AND '2009-06-29' BETWEEN ot.datestart AND ot.dateend
LEFT OUTER JOIN openpauses op
ON u.id_users = op.id_users AND '2009-06-29' BETWEEN op.datestart AND op.dateend
LEFT OUTER JOIN pauses p
ON op.id_pause = p.id_pause
LEFT OUTER JOIN task t
ON t.id_task = ot.id_task
WHERE u.id_groups = '2'


Le principe, c'est d'afficher les noms des users qui ont une pause et/ou une tâche à effectuer à la date donnée. Donc, je veux pouvoir afficher les users qui ont, par exemple, une pause et une tâche, juste une tâche et juste une pause.
Ca fonctionne bien, mis à part le fait qu'il me donne les noms des users qui n'ont ni de tâche, ni de pause et j'aimerais pouvoir éviter ça.

J'avoue ne pas trop savoir comment faire. J'ai essayé de modifier ma requête en faisant tout ce qui me passait par la tête, mais soit il me donne tout, soit il ne me donne que les personnes qui ont à la fois des tâches et des pauses à effectuer.

Si quelqu'un comprend ma question (que j'ai du mal d'expliquer lol), est-ce qu'il voudrait jeter un oeil sur ma requête svp ?

Merci d'avance
LA GLOBULE
le 03/07/2009 à 09:11
LA GLOBULE
Le problème des jointures externes, c'est justement qu'elles retournent tous les utilisateurs même si ils n'ont pas de taches ou de pauses.
C'est le but d'une jointure externe.

J'avoue ne pas avoir trop réfléchi à ton problème, mais une solution possible est de filtrer les résultats avec PHP, ou alors de le faire avec deux réquetes SQL.
InTheMix
le 03/07/2009 à 09:32
InTheMix
Hello La GLOBULLE,

Merci pour ta réponse.
C'est vrai que ma question était un peu stupide.

Sinon, pour filtrer en PHP, ca devrait être assez simple puisque je récupère les données dans un tableau, il suffit que je test :

for($i=0;$i<sizeof($totaltab);$i++)
{
if(!empty($totaltab[$i][id_pause]) || !empty($totaltab[$i][id_task]))
{
// blablabla
}
}


Merci encore et bonne journée
LupusMic
le 03/07/2009 à 18:18
LupusMic
Union est ton ami dans ce cas !

Pour en revenir à ta requête SQL initiale, plusieurs précisions.

Le mot clé outer est inutile (left join se suffit).

Un left join ne doit être utilisé que lorsque nécessaire. C'est à dire lorsqu'il y a une relation n..0 entre deux tables, et que la table jointe n'est pas une condition de sélection, mais un ajout fonctionnel.

En d'autres termes, si tu écris : « je veux tout les utilisateurs avec leurs rendez-vous », tu fais un left join. Si a contrario tu écris « Je veux tout les utilisateurs qui ont un rendez-vous », tu fais un join normal.

Une fois qu'on a compris, c'est limpide. Mais il est vrai que ce n'est pas évident. Et la culture du monde PHP ne pousse pas à ce genre de requêtes propres (car MySQL a (avait ?) de grosses limites fonctionnelles et des performances désastreuses lorsqu'on l'utilise comme une base de données relationnelle avancée (je pense aux requêtes imbriquées, entre autres).
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
InTheMix
le 07/07/2009 à 08:09
InTheMix
Hello LupusMic

Merci beaucoup pour tes précisions, ca va m'aider pour cette requête et pour l'avenir :)

Merci encore et bonne journée :)
Répondre

Ecrire un message

Votre message vient d'être créé avec succès.
LoadingChargement en cours