Extraire des données a partir de 2 table

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Extraire des données a partir de 2 table

par ouckileou » 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)

par albat » 09 juin 2008, 23:06

Ouckileou++; :pouce:

par Cyrano » 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

par zeus » 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.

par caroube » 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.

par ouckileou » 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

par ouckileou » 09 juin 2008, 11:54

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

Une jointure sur 2 colonnes ça marche...

par caroube » 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 ...)

par ouckileou » 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;

par Invité » 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

par ouckileou » 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)

par binarios » 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

par ouckileou » 05 juin 2008, 17:54

Extraire des données a partir de 2 table

par Binarios » 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