Comment supprimer doublons s/ inner join

Signaler
Messages postés
87
Date d'inscription
samedi 28 août 2004
Statut
Membre
Dernière intervention
30 janvier 2014
-
cs_Malkuth
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
-
Bonjour à tous,



<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
Base Access2000 + D6 + TADOquery 




En exécutant une recherche avec ce qui suit



 





SELECT GRUME_H_NIOKI_.*, HIST_GRUME_H_NIOKI_.*





FROM GRUME_H_NIOKI_






           inner JOIN HIST_GRUME_H_NIOKI_






           ON GRUME_H_NIOKI_.ID_GRUME_H = HIST_GRUME_H_NIOKI_.ID_GRUME_H






 






Where





GRUME_H_NIOKI_.n_abat






 
Like 458



 




Ok il le fait,


mais alors avec autant de doublons que des registres qui se trouvent ds la


table HIST_GRUME_H_NIOKI_



 




Qq sait comment faire pour enlever tous ces doublons, SVP…


Merci
810mcu

10 réponses

Messages postés
87
Date d'inscription
samedi 28 août 2004
Statut
Membre
Dernière intervention
30 janvier 2014

Tj moi,
pour mieux comprendre le sujet

Table1
GRUME_H_NIOKI_
Champs
ID_GRUME_H,
N_ABAT,
...

Table2
HIST_GRUME_H_NIOKI_
Champs
ID_HIST_GRUNE_H,
ID_GRUME_H,
POSITION,
DATA_BE
...

la liaison GRUME_H_NIOKI_.ID_GRUME_H = HIST_GRUME_H_NIOKI_.ID_GRUME_H

merci a vs tous
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
32
Comprend pas bien ton problème.

Avec INNER JOIN, tu ne dois normalement avoir que les enregistrements des 2 tables qui sont liés entre-eux. Si tu as des doublons c'est qu'ils sont surrement en doublons dans les tables.

Au pire essaye avec un SELECT DISTINCT

---- Sevyc64  (alias Casy) ---- # LE PARTAGE EST NOTRE FORCE #   
Messages postés
87
Date d'inscription
samedi 28 août 2004
Statut
Membre
Dernière intervention
30 janvier 2014

Salut casy,
SELECT DISTINCT, ne passeras pas a cause de (SELECT GRUME_H_NIOKI_.*, HIST_GRUME_H_NIOKI_.* )

tout en sachant que
table1 GRUME_H_NIOKI_ n'as que 1 registre avec
Champs
ID_GRUME_H,
N_ABAT,
...

et que
table2 HIST_GRUME_H_NIOKI_ elle une multitude de registre avec ID_GRUME_H,
Champs
ID_HIST_GRUNE_H,
ID_GRUME_H,
POSITION,
DATA_BE
...

1 - l'idée est de listé (DBGrid, query) le seul registre de la
table GRUME_H_NIOKI_(Table1)
du champ N_ABAT,
via la procédure de recherche (Where GRUME_H_NIOKI_.n_abat Like 458)

2 - mais aussi de pouvoir faire des recherches sur des champs de la table HIST_GRUME_H_NIOKI_ (Table2)
en réinitialisant la fonction

tout en gardent l'affichage stand art
(l'idée est de listé (DBGrid, query) le seul registre de la )

au final
query = champs Table1 + Table2
possibilité de recherche dans tous les champs des 2 tables et
faire en sorte de n'afficher que celui de la table1 (ou il n'y as pas de possibilité de doublons)

je pense que c'est un peut plus clair
Merci
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
32
Donc si je comprend bien, une requette avec le critère de sélection ne renverra systématiquement qu'un seul enregistrement sur la table 1.

Par contre, sur la table 2, tu peux avoir multitude d'enregistrements liés à l'unique de la table 1.

A partir du moment ou tu renvoie des champs de la table 2, ta requette globale avec jointure te renverra donc autant de résultats que tu aura d'enregistrements liés dans la table 2 avec à chaque fois, pour les champs de a table 1, les valeurs dupliquées corresponds à l'unique enregistrement.

Ceci est le fonctionnement même de la jointure et est parfaitement logique. Il n'y a donc pas de doublons (sauf si tu en as dans la table 2)

Peut-etre faut-il que tu rajoute des critères de sélection dans le where concernant la table 2

Ou alors tu ne renvoie que les champs de la table 1 avec à ce moment là un SELECT DISTINCT et tu ne devrais avoir qu'un seul résultat dans ce cas.

---- Sevyc64  (alias Casy) ---- # LE PARTAGE EST NOTRE FORCE #   
Messages postés
87
Date d'inscription
samedi 28 août 2004
Statut
Membre
Dernière intervention
30 janvier 2014

et bien j'ai déjà essayé cela aussi

SELECT GRUME_H_NIOKI_.*, HIST_GRUME_H_NIOKI_.*
FROM GRUME_H_NIOKI_
inner JOIN HIST_GRUME_H_NIOKI_
ON GRUME_H_NIOKI_.ID_GRUME_H = HIST_GRUME_H_NIOKI_.ID_GRUME_H
where
HIST_GRUME_H_NIOKI_.ID_GRUME_H = GRUME_H_NIOKI_.ID_GRUME_H
and
GRUME_H_NIOKI_.n_abat
Like 460

autant de doublons que de registre ds la table2

meme que j'ai aussi renversé
where
GRUME_H_NIOKI_.ID_GRUME_H = HIST_GRUME_H_NIOKI_.ID_GRUME_H
et rien a faire...!!!
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
32
Oui, mais c'est normal.

La condition que tu as ajouter dans le where ne sert à rien puisque c'est celle de la jointure et c'est cette dernière qui l'assure déjà.

Donc ta requette maintenant est identique à la précédente.

Tel que tu pose ton problème, c'est le fonctionnement normal de la jointure que tu obtiens. Et dans ce sens là, il n'y a pas de doublons.

Si tu as trop de résultats, il faut que tu filtre les enregistrements de la table 2 sur d'autres critères (pas l'id de ta jointure, mais d'autres colonnes de ta table 2)

---- Sevyc64  (alias Casy) ---- # LE PARTAGE EST NOTRE FORCE #   
Messages postés
87
Date d'inscription
samedi 28 août 2004
Statut
Membre
Dernière intervention
30 janvier 2014

Tu as tout a fait raison Casy,
ma Table2 avait qq problèmes, je me suis rendu compte?
Des fois on focalise sur qq chose et le problème est ailleurs

2eme volet, là très franchement ne n'est aucune idée, et je ne sais pas si cella est possible de le faire via SQL(query) !!!

J'ai un peut compléter mon query, que voici
SELECT GRUME_H_NIOKI_.ID_GRUME_H, 
        GRUME_H_NIOKI_.N_ABAT, 
GRUME_H_NIOKI_.L_ABAT,  
GRUME_H_NIOKI_.ESSENCE, 
GRUME_H_NIOKI_.D_SAVE, 
GRUME_H_NIOKI_.B_SAVE, 
GRUME_H_NIOKI_.CORRESPOND, 
GRUME_H_NIOKI_.PERMIS, 
GRUME_H_NIOKI_.CHANTIER, 
GRUME_H_NIOKI_.N_EXPORT, 
 	Count(HIST_GRUME_H_NIOKI_.ID_HIST_GRUNE_H) AS Nombre FROM GRUME_H_NIOKI_
 INNER JOIN HIST_GRUME_H_NIOKI_ ON GRUME_H_NIOKI_.ID_GRUME_H = HIST_GRUME_H_NIOKI_.ID_GRUME_H
Where
HIST_GRUME_H_NIOKI_.POSITION 
Like 'GARE'
GROUP BY GRUME_H_NIOKI_.ID_GRUME_H, 
GRUME_H_NIOKI_.N_ABAT, 
GRUME_H_NIOKI_.L_ABAT, 
GRUME_H_NIOKI_.ESSENCE, 
GRUME_H_NIOKI_.D_SAVE, 
GRUME_H_NIOKI_.B_SAVE, 
GRUME_H_NIOKI_.CORRESPOND, 
GRUME_H_NIOKI_.PERMIS, 
GRUME_H_NIOKI_.CHANTIER, 
GRUME_H_NIOKI_.N_EXPORT

Jusque là ok exécution parfaite, je me retrouve avec
1 ligne Table1
et n lignes Table2

Est-ce possible tj avec le même query, parcourir tous les lignes Table1 d'aller a la dernière ligne de la Table2(correspondante ligne Table1) est procéder a la vérification de ces données,
Where
HIST_GRUME_H_NIOKI_.POSITION 
Like 'GARE'

Merci...,
Messages postés
87
Date d'inscription
samedi 28 août 2004
Statut
Membre
Dernière intervention
30 janvier 2014

Bonjour,
Oui avec une boucle ( while ou for) cela serais possible, oui boulot d'un programme.
Mais d'un autre cote cela serait aussi possible via un (query, SQL) ???

Quelque chose du genre
Qu'appelles-tu 'vérification de ces données' ?
-Table1 GRUME_H_NIOKI_.ID_GRUME_H,
--Table2 sélectionne les lignes avec ID_GRUME_H
---Va a la dernière ligne est vérifie si celle si
----(HIST_GRUME_H_NIOKI_.POSITION égal 'GARE')
-----Si oui le query le garde
-----Si non le query le rejette

-Suivant...
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
32
"...dernière ligne de la Table2..."

Le terme 'dernière ligne' ne veut rien dire en terme de base de données
En fait il faut que tu précise dans ta requette un ordre de tri (ORDER BY) sur un ou plusieurs champs (une date par exemple) pour pouvoir ensuite parler effectivement de première ou dernière ligne.

Ensuite si tu tri ton résultat selon un ordre, et que tu veux la dernière ligne, tu peux tout aussi bien trier dans l'ordre inverse et vouloir donc par conséquent la première ligne.
Dans cette hypothèse, tu peux faire en sorte avec une requette style SELECT TOP 1 de ne retourner alors que le tout premier résultat.

Donc faire une requette SELECT * ... ORDER BY ... de sorte à ce que la ligne qui t'interresse soit retournée en premier.
Modifier ta requette en SELECT TOP1 * ... ORDER BY, pour ne retourner finalement que cette ligne qui t'interresse.

"...parcourir tous les lignes Table1 d'aller a la dernière ligne de la Table2(correspondante ligne Table1)..."
Oui effectivement avec une boucle. Il faut faire une première requette sur la table 1, puis avec une boucle sur chacun des résultats de la première requette, faire la seconde comme je viens de te l'expliquer.

Le faire en une seule requette ?
Je dirais qu'à priori cela doit etre possible, mais un peu plus compliquer. Je ne peux pas te donner de solutions comme ça. Il me faudrait faire des tests au préalable et je n'ai pas de données sous la main.

L'idée serait de remplacer, je pense, dans la jointure, la table 2 par le résultat de la requette sur cette table.

---- Sevyc64  (alias Casy) ----
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
2
Disont avec :

TBL1 (ID)
TBL2 (ID,FKTBL1,DATE,TRUC_INT)

si tu veux récupérer
TBL1.ID, TBL2.ID quand : Le TBL2 avec la plus grande DATE correspondant au TBL1(Via Jointure sur TBL1.ID=TBL2.FKTBL1) à un TRUC_INT= 5

Je pense qu'une requette de se genre fonctionnerais :

SELECT
   ID1,
   ID2
FROM
   (
      SELECT
         TBL1.ID ID1,
         (
            --Vérifie que la ligne de TBL2 est la bonne condition
            SELECT
               TMP.ID
            FROM
               (
                  --Récupération de la "derniére" ligne grace au ORDER BY plus TOP
                  SELECT TOP(1)
                     TBL2.ID,
                     TBL2.TRUC_INT
                  FROM
                     TBL2
                  WHERE
                     TBL2.FKTBL1 = TBL1.ID
                  ORDER BY
                     TBL2.DATE DESC
               ) TMP
            WHERE
               TMP.TRUC_INT = 5
         ) ID2
      FROM
         TBL1
   )
--Ne sélection que les cas ou la ligne de TBL2 a bien été trouvé
WHERE
   ID2 IS NOT NULL;

J'ai rien tester, j'ai pas acess sous la main et je connais trés peu et je pense pas que se soit trés optimum non plus ^^"