OVH Cloud OVH Cloud

Comparaison de tables

16 réponses
Avatar
Alain TEYSSEDRE
Bonjour

J'ai 2 tables Table1 et Table2
qui ont comme champs Champs1, Champs2, Champs3 ...pour Table1
et ChampA, , ChampB, ChampC .. pour Table2

Je souhaite par code VBA supprimer de Table1 tous les enregistrements pour
lesquels
la valeur de Champ1 ne correspond à aucune valeur de ChampC dans table 2.

c'est surement évident mais ce soir j'y arrive pas !

merci pour votre aide

Alain

6 réponses

1 2
Avatar
Alain TEYSSEDRE
Suite à mon mail correctif (que je viens d'envoyer à l'instant et dont tu ne
pouvais
avoir connaissance la réponse devrait etre NON)

je dis "devrait etre" car je n'arrive pas à visualiser le resultat de ta
requette : elle ne me
retourne aucun enregistrement alors que dans ma base exemple j'ai 8
enregistrements
sur 34 qui satisfont au critère dans ma table 1 donc l'opération SELECT (ou
DELETE)
devrait concerner 26 enregistrements

cdlt
Alain



"Michel Walsh" a écrit dans le message
de news:%
Salut,


donc un simple IN ( ou =ANY ) devrait faire l'affaire:


DELETE *
FROM table1
WHERE champ1 IN ( SELECT champB FROM table2)


non?


Vanderghast, Access MVP




"Alain TEYSSEDRE" wrote in message
news:evc%
helas Trois fois Helas la requete est toujour vide ...

Si les valeurs de Champ1 de Table 1 sont
:Toto,Tata,Tutu,Titi,Toto,Tutu,Tata,Tutu, Tittii => total de 9
enregistrements
et les valeurs de ChampB de Table 2 sont : Zaza,Zozo,Toto,Zazi,Tutu =>
total

de 5 enregistrements

alors la requete doit permettre de DELETER ou (retourner) tous les
enregistrements
de tous les champs de Table1 dont on retrouve une valeur dans Table2 (il
s'agit des 5 enregistrements Toto,Tutu,Toto,Tutu, Tutu)

@+

Alain



En fait, si les enregistrement de table1 sous Champ1 ont les valeurs
{ 1,


2, 3 }

et table2.ChampB les valeurs { 1, 2, 4 }

alors,
SELECT Champ1, ChampB
FROM Table1, Table2
WHERE table1.Champ1 <>table2.ChampB

donne
1 2
1 4
2 1
2 4
3 1
3 2
3 4


toutes les lignes de champ1 apparaissent dans champB. Seules les
combinaisons (1 , 1) et ( 2, 2 ) ne furent pas retenues. Il faut
effacer

1 et 2 de table1 ? Si c'est bien cela, alors un simple IN est à
utiliser



SELECT Champ1
FROM table1
WHERE Camp1 = ANY( SELECT ChampB FROM table2)


( = ANY peut être remplacé par IN )



Le <> ALL, sa négation, NOT IN si on préfère, effacera
l'enregistrement



ayant 3 comme valeur de Champ1.



Donc, pour simplifier, vérifier si on désire


SELECT Champ1
FROM table1
WHERE Camp1 IN( SELECT ChampB FROM table2)


ou si on désire

SELECT Champ1
FROM table1
WHERE NOT Camp1 IN( SELECT ChampB FROM table2)



tout simplement... et utiliser un DELETE par la suite (qui devrait
fonctionner).


Vanderghast, Access MVP


"Alain TEYSSEDRE" wrote in
message


news:
Re-Bonjour

Bon ta requete Selection ==> super ça marche le résultat est OK

par contre moi aussi je croyais qu'il suffisait de remplacer SELECT
par



DELETE DISTINCTROW .. et la patatras Erreur ..."Impossible de
supprimer



dans les tables spécifiées !"

aurais tu une idée

Merci
Alain






"Michel Walsh" a écrit dans le
message

de news:
Salut,


Si il s'agit d'avoir les enregistrements de Table1 qui ne sont pas
retournés

par

SELECT Table1.*
FROM Table2, Table1
WHERE (([Table1].[Champ4]<>[Table2].[ChampB]));


alors:

SELECT Table1.*
FROM Table2 RIGHT JOIN Table1
ON Table1.champ4 <> table2.champB
WHERE Table2.ChampB Is Null


devrait le faire.


J'ai simplement commencé par remonter la comparaison entre tables
de





la
clause WHERE au join, dans la clause ON:

SELECT Table1.*
FROM Table2 INNER JOIN Table1
ON Table1.champ4 <> table2.champB

Plus de clause WHERE, mais tout à fait équivalent au premier
énoncé





(par
contre, on perd la grille de design). La seule différence qui
existe





entre
un join externe et ce join interne c'est justement de conserver
les





enregistrements qui n'apparaissent pas lors du join interne ! Ce
sont




CES
enregistrements qu'on veut pointer du doigt, et leur "signature"
c'est




qu'ils ont des NULL dans les colonnes de la table "non
préservée"...





Table2
dans notre cas. D'où la solution proposée.


Pour effacer, changer le SELECT par DELETE DISTINCTROW



Espérant être utile,
Vanderghast, Access MVP


"Alain TEYSSEDRE" wrote in
message


news:%
Bonjour Michel

Malheureusement ta suggestion ne me permet pas d'obtenir ce que
je






souhaite.

En fait je sais sélectionner les enregistrements de Table1 qui
m'interressent avec la requete:
SELECT Table1.*
FROM Table2, Table1
WHERE (([Table1].[Champ4]<>[Table2].[ChampB]));

Comme tu le comprends je ne compare les valeurs que de 2 champs,
(le





nombre
de champs de chaque Table est différent).

Ce que je n'arrive pas à faire c'est sélectionner (pour les
DELETER)





tous
les champs de
Table1 qui n'ont pas été sélectionnés dans ma requete ...

ps: pour etre complet j'ai actuellement ChampB de table2 qui est
de





type
Lien hypertexte
si vraiment cela était un obstacle incontournable je le
changerai




en
champ texte
@+
Alain



"Michel Walsh" a écrit
dans






le
message
de news:
Salut,


Peut-être quelque chose dans le genre:


DELETE DISTINCTROW table1.*
FROM table1 LEFT JOIN table2
ON table1.champ1 = table2.champA
AND
table1.champ2 = table2.champB
AND
... jusqu'à plus soif ...

WHERE table2.ChampDeLaCléPrimaire Is Null



Espérant être utile,
Vanderghast, Access MVP


"Alain TEYSSEDRE"
wrote







in
message
news:
Bonjour

J'ai 2 tables Table1 et Table2
qui ont comme champs Champs1, Champs2, Champs3 ...pour
Table1








et ChampA, , ChampB, ChampC .. pour Table2

Je souhaite par code VBA supprimer de Table1 tous les
enregistrements




pour
lesquels
la valeur de Champ1 ne correspond à aucune valeur de ChampC
dans







table
2.

c'est surement évident mais ce soir j'y arrive pas !

merci pour votre aide

Alain
































Avatar
Michel Walsh
Salut,



Essayer, dans Northwind:


SELECT Customers.*
FROM Customers
WHERE CustomerID NOT IN (SELECT CustomerID FROM Orders);


le résultat devrait être afficher quelques customers.

Reste à savoir s'il faut effacer ceux qui sont IN ou ceux qui sont NOT IN...


Attention: si on passe par la grille, parfois Access nous jette des " " et
l'énoncé pourrait paraître comme

"NOT IN ( SELECT ... )"

qui, sous SQL, devient

WHERE CustomerID = "NOT IN ( SELECT ... )"

ce qui n'est pas ce qu'on désire!




Vanderghast, Access MVP



"Alain TEYSSEDRE" wrote in message
news:

Suite à mon mail correctif (que je viens d'envoyer à l'instant et dont tu
ne

pouvais
avoir connaissance la réponse devrait etre NON)

je dis "devrait etre" car je n'arrive pas à visualiser le resultat de ta
requette : elle ne me
retourne aucun enregistrement alors que dans ma base exemple j'ai 8
enregistrements
sur 34 qui satisfont au critère dans ma table 1 donc l'opération SELECT
(ou

DELETE)
devrait concerner 26 enregistrements

cdlt
Alain



"Michel Walsh" a écrit dans le
message

de news:%
Salut,


donc un simple IN ( ou =ANY ) devrait faire l'affaire:


DELETE *
FROM table1
WHERE champ1 IN ( SELECT champB FROM table2)


non?


Vanderghast, Access MVP




"Alain TEYSSEDRE" wrote in
message


news:evc%
helas Trois fois Helas la requete est toujour vide ...

Si les valeurs de Champ1 de Table 1 sont
:Toto,Tata,Tutu,Titi,Toto,Tutu,Tata,Tutu, Tittii => total de 9
enregistrements
et les valeurs de ChampB de Table 2 sont : Zaza,Zozo,Toto,Zazi,Tutu =>
total

de 5 enregistrements

alors la requete doit permettre de DELETER ou (retourner) tous les
enregistrements
de tous les champs de Table1 dont on retrouve une valeur dans Table2
(il



s'agit des 5 enregistrements Toto,Tutu,Toto,Tutu, Tutu)

@+

Alain



En fait, si les enregistrement de table1 sous Champ1 ont les valeurs
{ 1,


2, 3 }

et table2.ChampB les valeurs { 1, 2, 4 }

alors,
SELECT Champ1, ChampB
FROM Table1, Table2
WHERE table1.Champ1 <>table2.ChampB

donne
1 2
1 4
2 1
2 4
3 1
3 2
3 4


toutes les lignes de champ1 apparaissent dans champB. Seules les
combinaisons (1 , 1) et ( 2, 2 ) ne furent pas retenues. Il faut
effacer

1 et 2 de table1 ? Si c'est bien cela, alors un simple IN est à
utiliser



SELECT Champ1
FROM table1
WHERE Camp1 = ANY( SELECT ChampB FROM table2)


( = ANY peut être remplacé par IN )



Le <> ALL, sa négation, NOT IN si on préfère, effacera
l'enregistrement



ayant 3 comme valeur de Champ1.



Donc, pour simplifier, vérifier si on désire


SELECT Champ1
FROM table1
WHERE Camp1 IN( SELECT ChampB FROM table2)


ou si on désire

SELECT Champ1
FROM table1
WHERE NOT Camp1 IN( SELECT ChampB FROM table2)



tout simplement... et utiliser un DELETE par la suite (qui devrait
fonctionner).


Vanderghast, Access MVP


"Alain TEYSSEDRE" wrote in
message


news:
Re-Bonjour

Bon ta requete Selection ==> super ça marche le résultat est OK

par contre moi aussi je croyais qu'il suffisait de remplacer
SELECT





par
DELETE DISTINCTROW .. et la patatras Erreur ..."Impossible de
supprimer



dans les tables spécifiées !"

aurais tu une idée

Merci
Alain






"Michel Walsh" a écrit dans
le





message
de news:
Salut,


Si il s'agit d'avoir les enregistrements de Table1 qui ne sont
pas






retournés
par

SELECT Table1.*
FROM Table2, Table1
WHERE (([Table1].[Champ4]<>[Table2].[ChampB]));


alors:

SELECT Table1.*
FROM Table2 RIGHT JOIN Table1
ON Table1.champ4 <> table2.champB
WHERE Table2.ChampB Is Null


devrait le faire.


J'ai simplement commencé par remonter la comparaison entre
tables






de
la
clause WHERE au join, dans la clause ON:

SELECT Table1.*
FROM Table2 INNER JOIN Table1
ON Table1.champ4 <> table2.champB

Plus de clause WHERE, mais tout à fait équivalent au premier
énoncé





(par
contre, on perd la grille de design). La seule différence qui
existe





entre
un join externe et ce join interne c'est justement de conserver
les





enregistrements qui n'apparaissent pas lors du join interne ! Ce
sont




CES
enregistrements qu'on veut pointer du doigt, et leur "signature"
c'est




qu'ils ont des NULL dans les colonnes de la table "non
préservée"...





Table2
dans notre cas. D'où la solution proposée.


Pour effacer, changer le SELECT par DELETE DISTINCTROW



Espérant être utile,
Vanderghast, Access MVP


"Alain TEYSSEDRE" wrote
in






message
news:%
Bonjour Michel

Malheureusement ta suggestion ne me permet pas d'obtenir ce
que







je
souhaite.

En fait je sais sélectionner les enregistrements de Table1 qui
m'interressent avec la requete:
SELECT Table1.*
FROM Table2, Table1
WHERE (([Table1].[Champ4]<>[Table2].[ChampB]));

Comme tu le comprends je ne compare les valeurs que de 2
champs,







(le
nombre
de champs de chaque Table est différent).

Ce que je n'arrive pas à faire c'est sélectionner (pour les
DELETER)





tous
les champs de
Table1 qui n'ont pas été sélectionnés dans ma requete ...

ps: pour etre complet j'ai actuellement ChampB de table2 qui
est







de
type
Lien hypertexte
si vraiment cela était un obstacle incontournable je le
changerai




en
champ texte
@+
Alain



"Michel Walsh" a écrit
dans






le
message
de news:
Salut,


Peut-être quelque chose dans le genre:


DELETE DISTINCTROW table1.*
FROM table1 LEFT JOIN table2
ON table1.champ1 = table2.champA
AND
table1.champ2 = table2.champB
AND
... jusqu'à plus soif ...

WHERE table2.ChampDeLaCléPrimaire Is Null



Espérant être utile,
Vanderghast, Access MVP


"Alain TEYSSEDRE"
wrote







in
message
news:
Bonjour

J'ai 2 tables Table1 et Table2
qui ont comme champs Champs1, Champs2, Champs3 ...pour
Table1








et ChampA, , ChampB, ChampC .. pour Table2

Je souhaite par code VBA supprimer de Table1 tous les
enregistrements




pour
lesquels
la valeur de Champ1 ne correspond à aucune valeur de
ChampC









dans
table
2.

c'est surement évident mais ce soir j'y arrive pas !

merci pour votre aide

Alain




































Avatar
Alain TEYSSEDRE
Ou est ce que je trouve Northwind ?

j'en ai entendu parler mais je ne l'ai jamais utilisée

Autrement as tu essayé dans nothwind pour voir si ça marche ?
(parceque ça devrait marcher dans n'importe quelle base non ?)

cdlt
Alain






"Michel Walsh" a écrit dans le message
de news:
Salut,



Essayer, dans Northwind:


SELECT Customers.*
FROM Customers
WHERE CustomerID NOT IN (SELECT CustomerID FROM Orders);


le résultat devrait être afficher quelques customers.

Reste à savoir s'il faut effacer ceux qui sont IN ou ceux qui sont NOT
IN...



Attention: si on passe par la grille, parfois Access nous jette des " " et
l'énoncé pourrait paraître comme

"NOT IN ( SELECT ... )"

qui, sous SQL, devient

WHERE CustomerID = "NOT IN ( SELECT ... )"

ce qui n'est pas ce qu'on désire!




Vanderghast, Access MVP



"Alain TEYSSEDRE" wrote in message
news:

Suite à mon mail correctif (que je viens d'envoyer à l'instant et dont
tu


ne
pouvais
avoir connaissance la réponse devrait etre NON)

je dis "devrait etre" car je n'arrive pas à visualiser le resultat de ta
requette : elle ne me
retourne aucun enregistrement alors que dans ma base exemple j'ai 8
enregistrements
sur 34 qui satisfont au critère dans ma table 1 donc l'opération SELECT
(ou

DELETE)
devrait concerner 26 enregistrements

cdlt
Alain



"Michel Walsh" a écrit dans le
message

de news:%
Salut,


donc un simple IN ( ou =ANY ) devrait faire l'affaire:


DELETE *
FROM table1
WHERE champ1 IN ( SELECT champB FROM table2)


non?


Vanderghast, Access MVP




"Alain TEYSSEDRE" wrote in
message


news:evc%
helas Trois fois Helas la requete est toujour vide ...

Si les valeurs de Champ1 de Table 1 sont
:Toto,Tata,Tutu,Titi,Toto,Tutu,Tata,Tutu, Tittii => total de 9
enregistrements
et les valeurs de ChampB de Table 2 sont : Zaza,Zozo,Toto,Zazi,Tutu
=>




total
de 5 enregistrements

alors la requete doit permettre de DELETER ou (retourner) tous les
enregistrements
de tous les champs de Table1 dont on retrouve une valeur dans Table2
(il



s'agit des 5 enregistrements Toto,Tutu,Toto,Tutu, Tutu)

@+

Alain



En fait, si les enregistrement de table1 sous Champ1 ont les
valeurs





{ 1,
2, 3 }

et table2.ChampB les valeurs { 1, 2, 4 }

alors,
SELECT Champ1, ChampB
FROM Table1, Table2
WHERE table1.Champ1 <>table2.ChampB

donne
1 2
1 4
2 1
2 4
3 1
3 2
3 4


toutes les lignes de champ1 apparaissent dans champB. Seules les
combinaisons (1 , 1) et ( 2, 2 ) ne furent pas retenues. Il
faut





effacer
1 et 2 de table1 ? Si c'est bien cela, alors un simple IN est à
utiliser



SELECT Champ1
FROM table1
WHERE Camp1 = ANY( SELECT ChampB FROM table2)


( = ANY peut être remplacé par IN )



Le <> ALL, sa négation, NOT IN si on préfère, effacera
l'enregistrement



ayant 3 comme valeur de Champ1.



Donc, pour simplifier, vérifier si on désire


SELECT Champ1
FROM table1
WHERE Camp1 IN( SELECT ChampB FROM table2)


ou si on désire

SELECT Champ1
FROM table1
WHERE NOT Camp1 IN( SELECT ChampB FROM table2)



tout simplement... et utiliser un DELETE par la suite (qui devrait
fonctionner).


Vanderghast, Access MVP


"Alain TEYSSEDRE" wrote in
message


news:
Re-Bonjour

Bon ta requete Selection ==> super ça marche le résultat est OK

par contre moi aussi je croyais qu'il suffisait de remplacer
SELECT





par
DELETE DISTINCTROW .. et la patatras Erreur ..."Impossible de
supprimer



dans les tables spécifiées !"

aurais tu une idée

Merci
Alain






"Michel Walsh" a écrit
dans






le
message
de news:
Salut,


Si il s'agit d'avoir les enregistrements de Table1 qui ne sont
pas






retournés
par

SELECT Table1.*
FROM Table2, Table1
WHERE (([Table1].[Champ4]<>[Table2].[ChampB]));


alors:

SELECT Table1.*
FROM Table2 RIGHT JOIN Table1
ON Table1.champ4 <> table2.champB
WHERE Table2.ChampB Is Null


devrait le faire.


J'ai simplement commencé par remonter la comparaison entre
tables






de
la
clause WHERE au join, dans la clause ON:

SELECT Table1.*
FROM Table2 INNER JOIN Table1
ON Table1.champ4 <> table2.champB

Plus de clause WHERE, mais tout à fait équivalent au premier
énoncé





(par
contre, on perd la grille de design). La seule différence qui
existe





entre
un join externe et ce join interne c'est justement de
conserver







les
enregistrements qui n'apparaissent pas lors du join interne !
Ce







sont
CES
enregistrements qu'on veut pointer du doigt, et leur
"signature"







c'est
qu'ils ont des NULL dans les colonnes de la table "non
préservée"...





Table2
dans notre cas. D'où la solution proposée.


Pour effacer, changer le SELECT par DELETE DISTINCTROW



Espérant être utile,
Vanderghast, Access MVP


"Alain TEYSSEDRE"
wrote







in
message
news:%
Bonjour Michel

Malheureusement ta suggestion ne me permet pas d'obtenir ce
que







je
souhaite.

En fait je sais sélectionner les enregistrements de Table1
qui








m'interressent avec la requete:
SELECT Table1.*
FROM Table2, Table1
WHERE (([Table1].[Champ4]<>[Table2].[ChampB]));

Comme tu le comprends je ne compare les valeurs que de 2
champs,







(le
nombre
de champs de chaque Table est différent).

Ce que je n'arrive pas à faire c'est sélectionner (pour les
DELETER)





tous
les champs de
Table1 qui n'ont pas été sélectionnés dans ma requete ...

ps: pour etre complet j'ai actuellement ChampB de table2 qui
est







de
type
Lien hypertexte
si vraiment cela était un obstacle incontournable je le
changerai




en
champ texte
@+
Alain



"Michel Walsh" a écrit
dans






le
message
de news:
Salut,


Peut-être quelque chose dans le genre:


DELETE DISTINCTROW table1.*
FROM table1 LEFT JOIN table2
ON table1.champ1 = table2.champA
AND
table1.champ2 = table2.champB
AND
... jusqu'à plus soif ...

WHERE table2.ChampDeLaCléPrimaire Is Null



Espérant être utile,
Vanderghast, Access MVP


"Alain TEYSSEDRE"
wrote







in
message
news:
Bonjour

J'ai 2 tables Table1 et Table2
qui ont comme champs Champs1, Champs2, Champs3 ...pour
Table1








et ChampA, , ChampB, ChampC .. pour Table2

Je souhaite par code VBA supprimer de Table1 tous les
enregistrements




pour
lesquels
la valeur de Champ1 ne correspond à aucune valeur de
ChampC









dans
table
2.

c'est surement évident mais ce soir j'y arrive pas !

merci pour votre aide

Alain








































Avatar
Michel Walsh
Salut,


Cela fonctionne dans Northwind.

Est-ce qu'il y a un NULL comme valeur de champB dans


WHERE champ1 NOT IN ( SELECT champB FROM .... ) ?


Si oui, c'est le problème. En effet:


NOT x IN( u, v, w )

se traduit:

NOT ( x=u OR x=v OR x=w )

soit

x<>u AND x<>v AND x<>w ( Loi de de Morgan )

maintenant, si u = 2, v=3 et w = Null

x<>2 AND x<>3 AND x<>NULL

testons avec x = 222 par exemple:

FALSE AND FALSE AND NULL

(car 222 <> NULL retourne NULL)

ce qui donne

NULL

et NULL n'est pas vrai, ni faux, NULL est inconnu (logique à trois valeurs,
vrai, faux, inconnnu).


Donc, en conclusion, si il y a un NULL dans champB,

WHERE NOT x IN (SELECT champB FROM ... )

ne sera JAMAIS vrai, quelque soit x, et aucun enregistrement n'en sortira!


WHERE NOT x IN (SELECT champB FROM quelquePart WHERE NOT champB Is Null )

est préférable!


OK, maintenant, si il y a un petit curieux dans la salle qui essaie:


WHERE NOT x IN ( 2, 5, NULL)

ce petit curieux trouvera qu'il y a des enregistrements qui sont
retournés... sous Jet, pas sous MS SQL Server. C'est que Jet essaie d'être
aimable et sachant que cela ne fait pas de sens, enlève le NULL des
comparisons, dans le cas d'une "IN -liste de constantes". Mais PAS pour une
"IN-liste SELECT ".


Voilà, peut-être était-ce le problème, sinon, c'est quand même d'intérêt
didactique, je suppose... :-)


Où est Northwind.mdb? quand on installe Office, il faut, sous Access,
ou sous "Common", cocher d'installer les bases de données exemples... il me
semble.


Vanderghast, Access MVP




"Alain TEYSSEDRE" wrote in message
news:
Ou est ce que je trouve Northwind ?

j'en ai entendu parler mais je ne l'ai jamais utilisée

Autrement as tu essayé dans nothwind pour voir si ça marche ?
(parceque ça devrait marcher dans n'importe quelle base non ?)

cdlt
Alain




Avatar
Michel Walsh
Salut


après:

x<>2 AND x<>3 AND x<>NULL

testons avec x = 222 par exemple:

Fallait lire:

TRUE AND TRUE AND NULL


et non

FALSE AND FALSE AND NULL

(expression qui, elle, retourne toujours False).


La conclusion tient.



Vanderghast, Access MVP
Avatar
Alain TEYSSEDRE
Bonjour Michel

Extra super génial ....ça marche

Merci pour la solution et aussi pour les explications ....

Bonne journée
Alain




"Michel Walsh" a écrit dans le message
de news:%
Salut


après:

x<>2 AND x<>3 AND x<>NULL

testons avec x = 222 par exemple:

Fallait lire:

TRUE AND TRUE AND NULL


et non

FALSE AND FALSE AND NULL

(expression qui, elle, retourne toujours False).


La conclusion tient.



Vanderghast, Access MVP




1 2