Oui, je parlais bien de ttop mais aussi de infotop qui t'est aussi ramené par une jointure gauche.
Après, il ne suffit pas de rajouter des IS NULL, mais il faut bien réfléchir à ce que la requête va pouvoir ramener comme résultat lorsque les champs (l'un, l'autre, ou les deux) sont nuls et donc que le filtre ne s'applique plus.
Dans le cas présent, tu peux essayer, mais je pense que le résultat ne te conviendra pas,car à mon avis la requête ne correspond pas au besoin exprimé.
Reprenons :
Je cherche à récupérer dans une requête tous les contacts qui ont au moins un événement
Déjà, allons au plus simple :
1 2 3
| SELECT contacts.idcontact
FROM contacts
INNER JOIN evenements ON contacts.idcontact = evenements.idcontact |
Puisqu'il faut qu'il y est au moins un événement donc un enregistrement dans la table jointe, ça exclut de fait les null. On est bien sur une jointure interne.
en excluant les contacts qui ont un événement de type "type2"
Donc bêtement, toujours au plus simple :
WHERE evenement.type <> "type2"
sauf s'il existe un événement de type "type1" dont la date de création est supérieur à la date de création de l'événement "type 2"
Aie, ici ça se complique.
Déjà, faisons la différence entre une jointure et un filtre (les filtres se font dans la clause where, et, par pitié, non, on ne met pas les conditions de jointure dans les clause where, n'en déplaise aux profs d'école informatique qui ne vont pas assez sur le terrain).
Une jointure est faite pour ramener dans le jeu de résultats des champs qui n'appartiennent pas à la table interrogée, mais à une autre table, et ce sous certaines conditions.
Le filtre, lui, sert à exclure ou à autoriser (et donc implicitement à exclure ce qui n'est pas autorisé) du jeu de résultats certains des enregistrements qui pourraient être ramenés par la requête.
Dans l'expression sauf s'il existe un événement de type "type1" dont la date de création est supérieur à la date de création de l'événement "type 2", on a est plus à exclure (ou ne pas exclure) des enregistrements, plutôt que d'aller chercher des champs supplémentaires. On peut donc a priori penser que l'on travaille plutôt sur la clause WHERE et non pas sur une jointure.
On en était donc à
en excluant les contacts qui ont un événement de type "type2" sauf
Déjà on peut traduire ça par :
WHERE evenement.type <> "type2" OR (evenement.type = "type2" AND ???????)
Pour les ??????,
s'il existe un événement de type "type1" dont la date de création est supérieure à la date de création de l'événement "type 2"
Ben on va traduire bêtement (en espérant que l'instruction EXISTS existe sous MySQL)
EXISTS(SELECT * FROM evenement ev2 WHERE ev2.idcontact=contacts.idcontact AND ev2.type="type1" AND ev2.datecrea > evenement.datecrea)
Donc ici, pour un éventuel enregistrement dont l’événement est de type 2, on vient donc rechercher dans la table evenement, s'il existe des enregistrements, correspondant au même contact, étant de type 1, dont la date de création est supérieure à notre événement de type 2. Je pense que l'on remplit la condition.
1 2 3 4
| SELECT contacts.idcontact
FROM contacts
INNER JOIN evenements ON contacts.idcontact = evenements.idcontact
WHERE evenement.type <> "type2" OR (evenement.type = "type2" AND EXISTS(SELECT * FROM evenement ev2 WHERE ev2.idcontact=contacts.idcontact AND ev2.type="type1" AND ev2.datecrea > evenement.datecrea)) |
En espérant ne pas avoir fait d'erreur.
EDIT : J'avais bien fait une erreur sur la jointure, la malédiction du copier/coller
Partager