[R]Un problème basique sur MYSQL, quelqu'un peut-il m'aider.

Consultez la formation au référencement naturel Google de WebRankInfo / Ranking Metrics

John Smith
WRInaute impliqué
WRInaute impliqué
 
Messages: 381
Inscription: Mer Avr 04, 2007 11:53

[R]Un problème basique sur MYSQL, quelqu'un peut-il m'aider.

Message le Mer Jan 16, 2008 22:08

Bonsoir,

Le problème est assez simple :

J'ai deux tables MySQL. Une est remplie d'éléments, l'autre vide.

Quand je sélectionne un élément dans la première table, cet élément est inséré dans la deuxième table (sans pour autant être effacé dans la première).

Le problème se pose car je n'arrive pas à sélectionner dans la première table tous les éléments sauf ceux qui ont été inscrit dans la deuxième table.
J'avais pensé à un truc du genre :

SELECT DISTINCT tab1.id from tab1, tab2 where tab1.id <> tab2.id

Mais ça ne marche pas. Alors quelle requête doit-on écrire pour sélectionner les éléments d'une table qui n'appartiennent pas à une deuxième table.

Merci de m'apporter vos lumières.
Dernière édition par John Smith le Jeu Jan 17, 2008 22:16, édité 1 fois.


druart
WRInaute accro
WRInaute accro
 
Messages: 1664
Inscription: Dim Avr 30, 2006 8:08

Message le Mer Jan 16, 2008 22:11

Bonsoir,

Je pencherai vers une recherche vers "not in" plutôt que vers "<>" (demande à notre ami Google)


(ma lumière est faible ce soir)

javases
Nouveau WRInaute
 
Messages: 12
Inscription: Mar Jan 15, 2008 1:44

Message le Mer Jan 16, 2008 23:00

select id from table1 where id not in (select id from table2)

jcaron
WRInaute accro
WRInaute accro
 
Messages: 1139
Inscription: Ven Fév 13, 2004 20:33

Re: Un problème basique sur MYSQL, quelqu'un peut-il m'aider

Message le Mer Jan 16, 2008 23:04

John Smith a écrit:Le problème se pose car je n'arrive pas à sélectionner dans la première table tous les éléments sauf ceux qui ont été inscrit dans la deuxième table.
J'avais pensé à un truc du genre :

SELECT DISTINCT tab1.id from tab1, tab2 where tab1.id <> tab2.id

Mais ça ne marche pas. Alors quelle requête doit-on écrire pour sélectionner les éléments d'une table qui n'appartiennent pas à une deuxième table.


SELECT tab1.id FROM tab1 WHERE NOT EXISTS (SELECT tab2.id FROM tab2 WHERE tab2.id=tab1.id);

SELECT tab1.id FROM tab1 EXCEPT SELECT tab2.id FROM tab2;

Jacques.

John Smith
WRInaute impliqué
WRInaute impliqué
 
Messages: 381
Inscription: Mer Avr 04, 2007 11:53

Message le Jeu Jan 17, 2008 11:44

Merci de vos réponses, j'essaierai ce soir et vous direz pour quelle solution j'ai optée.

John Smith
WRInaute impliqué
WRInaute impliqué
 
Messages: 381
Inscription: Mer Avr 04, 2007 11:53

Message le Jeu Jan 17, 2008 22:15

Eh bien, j'ai fait un mix de tout et ce qui marche chez moi c'est :

Code: Tout sélectionner
SELECT DISTINCT tab1.id FROM tab1 WHERE tab2.id NOT IN(SELECT tab2.id FROM tab2 WHERE tab2.id=tab1.id)


Encore merci de vos précieux conseils.

jcaron
WRInaute accro
WRInaute accro
 
Messages: 1139
Inscription: Ven Fév 13, 2004 20:33

Message le Jeu Jan 17, 2008 22:40

John Smith a écrit:Eh bien, j'ai fait un mix de tout et ce qui marche chez moi c'est :

Code: Tout sélectionner
SELECT DISTINCT tab1.id FROM tab1 WHERE tab2.id NOT IN(SELECT tab2.id FROM tab2 WHERE tab2.id=tab1.id)



Euuuuh... Je ne crois pas trop, non. Je pense qu'il y a au moins 2 erreurs (de recopie?). A part le WHERE tab2.id NOT IN qui doit évidemment être WHERE tab1.id NOT IN (tab2 n'est pas visible dans la requête principale), la clause WHERE de requête équivaut à:

tab1.id NOT IN (tab1.id)

soit:

tab1.id <> tab1.id

soit:

0

Bref, ça ne renvoie jamais rien.

Donc si ta requête fonctionne, je pense que ce n'est pas celle là :-)

Jacques.

John Smith
WRInaute impliqué
WRInaute impliqué
 
Messages: 381
Inscription: Mer Avr 04, 2007 11:53

Message le Ven Jan 18, 2008 12:31

Oui autant pour moi, heureusement qu'il y en a qui suivent ! C'est bien :

Code: Tout sélectionner
SELECT DISTINCT tab1.id FROM tab1 WHERE tab1.id NOT IN (SELECT tab2.id FROM tab2 WHERE tab2.id=tab1.id)


Les noms de mes tables à l'origine ne sont pas ceux-là et la requête à d'autres conditions aussi, j'ai fait l'erreur en voulant la retranscrire de manière simplifiée. :roll:

jcaron
WRInaute accro
WRInaute accro
 
Messages: 1139
Inscription: Ven Fév 13, 2004 20:33

Message le Ven Jan 18, 2008 12:54

John Smith a écrit:Oui autant pour moi, heureusement qu'il y en a qui suivent ! C'est bien :

Code: Tout sélectionner
SELECT DISTINCT tab1.id FROM tab1 WHERE tab1.id NOT IN (SELECT tab2.id FROM tab2 WHERE tab2.id=tab1.id)


Les noms de mes tables à l'origine ne sont pas ceux-là et la requête à d'autres conditions aussi, j'ai fait l'erreur en voulant la retranscrire de manière simplifiée. :roll:


Ca corrige une des deux erreurs, mais ça ne fait toujours pas ce que tu veux. Comme déjà dit, c'est équivalent à tab1.id NOT IN (tab1.id) donc à tab1.id <> tab1.id donc 0, donc pas de résultats.

Donc au choix:
- tu utilises NOT IN, et tu utilises la liste entière dans tab2: tab1.id NOT IN (SELECT tab2.id FROM tab2) comme indiqué par javases;
- tu utilises NOT EXISTS, et dans ce cas tu qualifies avec la comparaison: NOT EXISTS (SELECT tab2.id FROM tab2 WHERE tab2.id=tab1.id)
- tu utilises EXCEPT

Note que je ne sais pas si les deux derniers existent dans mysql (et/ou dans quelles versions), mais avec postgresql ça marcherait impec. Note qu'à moins que le planner soit super intelligent (et en fonction des tailles respectives de tab1 et tab2 et des index existants), la méthode du NOT EXISTS est probablement la plus efficace.

Jacques.

John Smith
WRInaute impliqué
WRInaute impliqué
 
Messages: 381
Inscription: Mer Avr 04, 2007 11:53

Message le Ven Jan 18, 2008 18:19

Ben pourtant ça marche chez moi.

J'ai admettons 100 éléments dans ma tab1, je vois ma tab2 se remplir progressivement et le résultat se décrémenter au fur et à mesure que je rempli tab2.

J'ai peut-être un bug mais pour l'instant, il est pas apparent. Je donne exactement ma requête telle qu'elle existe sur mon site, peut-être que j'ai fait une erreur de trascription :

Code: Tout sélectionner
SELECT DISTINCT ".TABLE_AUTEUR_OEUVRES.".id FROM ".TABLE_AUTEUR_OEUVRES." WHERE type = 'originale' AND statut = 1 AND isRecueil = 0 AND ".TABLE_AUTEUR_OEUVRES.".id NOT IN (SELECT ".TABLE_AUTEUR_OEUVRES_JOUR.".oeuvre_id FROM ".TABLE_AUTEUR_OEUVRES_JOUR." WHERE ".TABLE_AUTEUR_OEUVRES_JOUR.".oeuvre_id=".TABLE_AUTEUR_OEUVRES.".id)


Cela me permet d'afficher une oeuvre par jour tirée au hasard dans ma base selon certaines conditions... Les TABLE... sont des constantes PHP...

jcaron
WRInaute accro
WRInaute accro
 
Messages: 1139
Inscription: Ven Fév 13, 2004 20:33

Message le Ven Jan 18, 2008 19:01

John Smith a écrit:Ben pourtant ça marche chez moi.


Ah ouaip finalement en réfléchissant un peu (ça m'arrive des fois :P ) ça marche, le subselect renvoie soit tab1.id s'il est présent dans tab2, soit rien sinon, donc ça donne le résultat escompté au final. Mais ce n'est à mon avis pas la forme la plus lisible qui soit, et probablement pas la plus efficace, mais bon, tant que ça marche :-)

Jacques.


Formation recommandée sur ce thème :

Formation Référencement naturel Google : apprenez une méthode efficace pour optimiser à fond le référencement naturel dans Google de façon durable... Formation animée par Olivier Duffez et Fabien Facériès, experts en référencement naturel.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: carrel et 0 invités