Disons que j'ai trois tables A, B et C. Chacune a deux colonnes: une clé primaire et une autre donnée. Ils ont chacun le même nombre de lignes. Si je JOIN
A et B sur la clé primaire, je devrais me retrouver avec le même nombre de lignes que dans l'une d'elles (par opposition à A.rows * B.rows).
Maintenant, si je JOIN
A JOIN B
avec C
, pourquoi me retrouve-t-il avec des lignes en double? J'ai rencontré ce problème à plusieurs reprises et je ne le comprends pas. Il semble que cela devrait produire le même résultat que JOIN
ing A
et B
puisqu'il contient le même nombre de lignes mais que des doublons sont générés.
Les requêtes qui produisent de tels résultats sont au format
SELECT *
FROM M
INNER JOIN S
on M.mIndex = S.mIndex
INNER JOIN D
ON M.platformId LIKE '%' + D.version + '%'
INNER JOIN H
ON D.Name = H.Name
AND D.revision = H.revision
Voici les schémas pour les tables. H contient est un tableau historique contenant tout ce qui a jamais été en D. Il y a beaucoup de lignes M pour chaque D et un S pour chaque M.
Tableau m
[mIndex] [int] NOT NULL PRIMARY KEY,
[platformId] [nvarchar](256) NULL,
[ip] [nvarchar](64) NULL,
[complete] [bit] NOT NULL,
[date] [datetime] NOT NULL,
[DeployId] [int] NOT NULL PRIMARY KEY REFERENCES D.DeployId,
[source] [nvarchar](64) NOT NULL PRIMARY KEY
Les tables
[order] [int] NOT NULL PRIMARY KEY,
[name] [nvarchar](64) NOT NULL,
[parameters] [nvarchar](256) NOT NULL,
[Finished] [bit] NOT NULL,
[mIndex] [int] NOT NULL PRIMARY KEY,
[mDeployId] [int] NOT NULL PRIMARY KEY,
[Date] [datetime] NULL,
[status] [nvarchar](10) NULL,
[output] [nvarchar](max) NULL,
[config] [nvarchar](64) NOT NULL PRIMARY KEY
Tableau d
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[branch] [nvarchar](64) NOT NULL,
[revision] [int] NOT NULL,
[version] [nvarchar](64) NOT NULL,
[path] [nvarchar](256) NOT NULL
Tableau h
[IdDeploy] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](64) NOT NULL,
[version] [nvarchar](64) NOT NULL,
[path] [nvarchar](max) NOT NULL,
[StartDate] [datetime] NOT NULL,
[EndDate] [datetime] NULL,
[Revision] [nvarchar](64) NULL,
Je n'ai pas posté les tables et interrogé initialement parce que je suis plus intéressé à comprendre ce problème par moi-même et à l'éviter à l'avenir.
Si l’une des tables M
, S
, D
ou H
a plus d’une ligne pour un Id
donné (si seulement la colonne Id
n’est pas la clé primaire), la requête aboutirait à des lignes "en double". Si vous avez plus d'une ligne pour un Id
dans une table, les autres colonnes, qui identifieraient de manière unique une ligne, doivent également être incluses dans la ou les conditions JOIN.
Références :
Lorsque vous avez des tables associées, vous avez souvent des relations un à plusieurs ou plusieurs à plusieurs. Ainsi, lorsque vous rejoignez TableB, chaque enregistrement de TableA contient plusieurs enregistrements dans TableB. Ceci est normal et attendu.
Parfois, vous n'avez besoin que de certaines colonnes et celles-ci sont identiques pour tous les enregistrements. Vous devez alors créer une sorte de groupe par ou distinct pour supprimer les doublons. Regardons un exemple:
TableA
Id Field1
1 test
2 another test
TableB
ID Field2 field3
1 Test1 something
1 test1 More something
2 Test2 Anything
Donc, lorsque vous les rejoignez et sélectionnez tous les fichiers que vous obtenez:
select *
from tableA a
join tableb b on a.id = b.id
a.Id a.Field1 b.id b.field2 b.field3
1 test 1 Test1 something
1 test 1 Test1 More something
2 another test 2 2 Test2 Anything
Ce ne sont pas des doublons car les valeurs de Field3 sont différentes même s'il existe des valeurs répétées dans les champs précédents. Désormais, lorsque vous ne sélectionnez que certaines colonnes, le même nombre d'enregistrements sont joints mais, comme les colonnes contenant les différentes informations ne sont pas affichées, elles ressemblent à des doublons.
select a.Id, a.Field1, b.field2
from tableA a
join tableb b on a.id = b.id
a.Id a.Field1 b.field2
1 test Test1
1 test Test1
2 another test Test2
Cela semble être des doublons, mais ce n'est pas à cause des enregistrements multiples dans TableB.
Vous corrigez normalement cela en utilisant des agrégats et un groupe par, en utilisant distinct ou en filtrant dans la clause where pour supprimer les doublons. Votre solution dépend de la nature exacte de votre règle métier, de la conception de votre base de données et du type de données qu’elle contient.
Cela peut sembler une réponse "DUH" très basique, mais assurez-vous que la colonne que vous utilisez pour la recherche dans le fichier de fusion est en réalité pleine de valeurs uniques!
J'ai remarqué plus tôt dans la journée que PowerQuery ne vous lança pas d'erreur (comme dans PowerPivot) et vous autoriserait à exécuter une fusion plusieurs-plusieurs. Cela entraînera la production de plusieurs lignes pour chaque enregistrement correspondant à une valeur non unique.
Ok dans cet exemple, vous obtenez des doublons parce que vous joignez D et S à M. Je suppose que vous devriez joindre D.id à S.id comme ci-dessous:
SELECT *
FROM M
INNER JOIN S
on M.Id = S.Id
INNER JOIN D
ON S.Id = D.Id
INNER JOIN H
ON D.Id = H.Id