Extraire des données a partir de 2 table

Binarios
Invité n'ayant pas de compte PHPfrance

05 juin 2008, 17:17

Bonjour
j'ai deux table ( avec 2clés Salle_id, Patient_ID dans chaque table) , comment faire pour creer une requette sql que retourne seulement les enregisterment de la table 1 et que ne sont pas dans la table 2,
NB les deux enregistrement egaux ont la meme Patient_iD et Salle_id
et merci d'avance

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

05 juin 2008, 17:54


binarios
Invité n'ayant pas de compte PHPfrance

06 juin 2008, 14:29

merci pour cette page,
mais moi j'ai deux table, et deux clé dans chaque table
par exemple
table1(cle1,cle2,champsX.....)
table2(cle1,cle2,champsY.....)

table1 : eng1, eng2, eng3
table2 : eng1, eng2,

requette doit retourner le eng 3

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 juin 2008, 15:20

Dans l'autre sujet aussi il y a 2 tables, une seule clé certes mais ça n'est pas bien compliqué à adapter...

Je recible le lien : http://www.phpfrance.com/forums/voir_re ... php#245370 (directement sur le bon sujet)

Invité
Invité n'ayant pas de compte PHPfrance

06 juin 2008, 16:09

je croix pas avec le deux clé c un peu difficle, 'ai essaye avec NOt in mais ca marche pas

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 juin 2008, 16:20

Mais pourquoi tu parles de NOT IN ? tu as regardé la requête de l'autre sujet au moins ?

Normalement tu as juste la jointure et le filtre à modifier, lui le fait sur 1 colonne, toi sur 2 :

Code : Tout sélectionner

SELECT t1.salle_id, t1.patient_id FROM table1 AS t1 LEFT OUTER JOIN table2 AS t2 ON t1.salle_id = t2.salle_id AND t1.patient_id = t2.patient_id WHERE t1.salle_id IS NULL AND t1.patient_id IS NULL;

Eléphant du PHP | 422 Messages

09 juin 2008, 11:26

j'ai deux table ( avec 2clés Salle_id, Patient_ID dans chaque table) , comment faire pour creer une requette sql que retourne seulement les enregisterment de la table 1 et que ne sont pas dans la table 2
Faisons simple d'abord avec une seule clé :
1) Les enregistrements qui sont dans la table 1 --> ça retourne une liste

Code : Tout sélectionner

select id from table1 ...
2) Les enregistrements de la table 2 qui ne sont pas dans la liste de la table 1

Code : Tout sélectionner

select * from table2 where id not in (select id from table1 ...)
Ton problème est que tu n'as pas une seule clé, mais deux clés. Donc comment transformer 2 clés en 1 seule. Tout simplement en les concaténant. Si ce sont des clés textes, pas de problème et si ce sont des clés numériques variant par exemple entre 0 et 100000, tu multiplies la première par 1 milliard (pour avoir beaucoup de marge) et tu ajoutes la seconde

Code : Tout sélectionner

select * from table2 where (id1*1000000000+id2) not in (select id1*1000000000+id2 from table1 ...)

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

09 juin 2008, 11:54

C'est pas un peu tarabiscotée comme solution ? :roll:

Une jointure sur 2 colonnes ça marche...

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

09 juin 2008, 12:19

Bon pour être sûr j'ai fait des tests :

Code : Tout sélectionner

CREATE TABLE `tests`.`table1` ( `cle1` TINYINT( 2 ) UNSIGNED NOT NULL , `cle2` TINYINT( 2 ) UNSIGNED NOT NULL , `libelle` VARCHAR( 50 ) NOT NULL , PRIMARY KEY ( `cle1` , `cle2` ) ) ENGINE = InnoDB CREATE TABLE `tests`.`table2` ( `cle1` TINYINT( 2 ) UNSIGNED NOT NULL , `cle2` TINYINT( 2 ) UNSIGNED NOT NULL , `libelle` VARCHAR( 50 ) NOT NULL , PRIMARY KEY ( `cle1` , `cle2` ) ) ENGINE = InnoDB INSERT INTO table1 (cle1, cle2, libelle) VALUES (1, 1, 'enregistrement 1 - présent dans les 2 tables'); INSERT INTO table1 (cle1, cle2, libelle) VALUES (2, 2, 'enregistrement 2 - présent dans les 2 tables'); INSERT INTO table1 (cle1, cle2, libelle) VALUES (3, 3, 'enregistrement 3 - présent dans les 2 tables'); INSERT INTO table1 (cle1, cle2, libelle) VALUES (4, 4, 'enregistrement 4 - présent dans table 1 uniquement'); INSERT INTO table1 (cle1, cle2, libelle) VALUES (5, 5, 'enregistrement 5 - présent dans table 1 uniquement'); INSERT INTO table1 (cle1, cle2, libelle) VALUES (6, 6, 'enregistrement 6 - présent dans les 2 tables'); INSERT INTO table2 (cle1, cle2, libelle) VALUES (1, 1, 'enregistrement 1 - présent dans les 2 tables'); INSERT INTO table2 (cle1, cle2, libelle) VALUES (2, 2, 'enregistrement 2 - présent dans les 2 tables'); INSERT INTO table2 (cle1, cle2, libelle) VALUES (3, 3, 'enregistrement 3 - présent dans les 2 tables'); INSERT INTO table2 (cle1, cle2, libelle) VALUES (6, 6, 'enregistrement 6 - présent dans les 2 tables');
On récupère toutes les lignes :

Code : Tout sélectionner

SELECT t1.cle1, t1.cle2, t2.cle1, t2.cle2, t1.libelle FROM table1 AS t1 LEFT OUTER JOIN table2 AS t2 ON t1.cle1 = t2.cle1 AND t1.cle2 = t2.cle2
Résultat :

Code : Tout sélectionner

cle1 cle2 cle1 cle2 libelle 1 1 1 1 enregistrement 1 - présent dans les 2 tables 2 2 2 2 enregistrement 2 - présent dans les 2 tables 3 3 3 3 enregistrement 3 - présent dans les 2 tables 4 4 NULL NULL enregistrement 4 - présent dans table 1 uniquement 5 5 NULL NULL enregistrement 5 - présent dans table 1 uniquement 6 6 6 6 enregistrement 6 - présent dans les 2 tables
Et maintenant que celles qui ne sont pas dans la table 2 :

Code : Tout sélectionner

SELECT t1.cle1, t1.cle2, t2.cle1, t2.cle2, t1.libelle FROM table1 AS t1 LEFT OUTER JOIN table2 AS t2 ON t1.cle1 = t2.cle1 AND t1.cle2 = t2.cle2 WHERE t2.cle1 IS NULL AND t2.cle2 IS NULL
Résultat :

Code : Tout sélectionner

cle1 cle2 cle1 cle2 libelle 4 4 NULL NULL enregistrement 4 - présent dans table 1 uniquement 5 5 NULL NULL enregistrement 5 - présent dans table 1 uniquement

Eléphant du PHP | 422 Messages

09 juin 2008, 18:38

C'est pas un peu tarabiscotée comme solution ? :roll:
Je ne sais pas.
Cela n'a sûrement pas l'élégance d'un OUTER JOIN à colonnes nulles, mais personnellement je trouve cela simple et compréhensible. Et en plus, c'est une "généralisation" du NOT IN sur une seule colonne. Et ça peut servir dans pas mal de cas comme des recherches de doublons sur plusieurs colonnes.
Mais il n'y a pas qu'une seule solution à un problème, donc chacun fait comme il se sent le mieux.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

09 juin 2008, 20:00

Au delà de l'envie de l'utiliser, j'ai dans l'idée que la solution d'ouckileou est beaucoup plus optimisée. :-k

Je tenterais bien quelques benchmark pour vérifier ça, appuyé d'EXPLAIN PLAN. J'ai dans l'idée que, comme la solution de caroube agit sur les valeurs, il n'y a aucun index d'utilisé, donc aucun performance.
Mais j'attends de tester pour voir.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 19672 Messages

09 juin 2008, 20:57

...la solution d'ouckileou est beaucoup plus optimisée...
J'y vois personnellement une excellente base de tuto sur ce genre de requête :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

09 juin 2008, 23:06

Ouckileou++; :pouce:

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

14 juin 2008, 14:21

Ce n'est pas une question d'élégance, ça fait une requête au lieu d'une. Mais surtout ce qui me gêne, c'est ta manipulation avec multiplication/concaténation des clés, à la place d'une double jointure qui marche aussi bien.


Par contre pour un tuto ça me paraît un peu léger comme contenu quand même, je ne vois pas ce qu'on pourrait dire de plus en fait. À la rigueur dans la FAQ (mais bon elle est un peu chargée dans la config actuelle, il faudrait attendre une catégorisation)