Запрос Left outer Join возвращает дубликаты в SQL Server


У меня есть стол 1 (MID, SSN, ...) MID является первичным ключом и таблица 2 (ID, SSN, StateCode..), где ID и SSN составляют первичный ключ. Я пытаюсь отобразить все столбцы из таблицы 1 вместе с StateCode из таблицы 2, сопоставив их с SSN. Tbl 1 содержит 50 строк, и некоторые из них имеют одинаковые значения SSN.

Если из таблицы 2 не найдено совпадения SSN, отображение NULL в StateCode допустимо, поэтому я выбрал левое соединение. Вот мой запрос

Select 
    tbl1.*, tbl2.StateCode
from 
    tbl1
left outer join 
    tbl2 on tbl1.SSN = tbl2.SSN

Я ищу, чтобы получить 50 записей, но я получаю 70 строк, которые содержать то же значение ssn в tbl1 в конечном итоге дублируется в конечном выходе. Что происходит не так?

6 2

6 ответов:

Я хотел бы предложить чтении декартово произведение.

Если у вас есть 50 строк в первой таблице и 70 во второй, это составляет 3500 строк. Условие соединения tbl1.SSN = tbl2.SSN отфильтрует строки, но вы вполне можете получить более 50 строк.

Возвращаясь к вашей проблеме, вы можете увидеть, что происходит, попробовав следующее:

SELECT 
  tbl1.*,
  (SELECT COUNT(*) FROM tbl2 WHERE tbl1.SSN = tbl2.SSN) AS NbResultTbl2
FROM 
  tbl1

Это покажет, какие строки tbl1 имеют несколько совпадений в tbl2. Если у вас есть число выше 1 в столбце NbResultTbl2, то вы идете чтобы в итоге получить дубликаты.

Чтобы устранить эти дубликаты, вы можете попробовать следующее:

SELECT 
  tbl1.*,
  (SELECT TOP 1 StateCode FROM tbl2 WHERE tbl1.SSN = tbl2.SSN) 
FROM 
  tbl1  

Это позволит получить первый StateCode найденный для соответствующего SNN в tbl2.

Попробуйте использовать SELECT DISTINCT вместо простого оператора SELECT, SELECT DISTINCT не будет показывать дубликаты

Попробуйте, В обеих ваших таблицах есть еще один первичный ключ, так что просто попробуйте столбец ID, чтобы соответствовать

Select tbl1.MID,tbl1.SSN, tbl2.StateCode
from tbl1
left outer join tbl2 
on tbl1.MID= tbl2.ID
Group by tbl1.MID,tbl1.SSN, tbl2.StateCode

Это слишком долго для комментария.

"ID и SSN являются первичными ключами". . . Это утверждение указывает на отсутствие понимания того, что такое первичный ключ. Таблица может иметь только один первичный ключ. Первичный ключ может быть составным (состоящим из нескольких столбцов), но существует только один.

Если MID является первичным ключом для таблицы 1, то предположительно несколько строк могут иметь один и тот же SSN.

Ваш запрос:

Select *
from tbl1, tbl2.StateCode
from tbl1, tbl2 left outer join tbl2 on tbl1.SSN = tbl2.SSN

Это даже не допустимый SQL. Вы можете попробовать эта версия:

Select distinct tbl1.*, tbl2.StateCode
from tbl1 left outer join
     tbl2
     on tbl1.SSN = tbl2.SSN;

Это действительно и, по-видимому, то, что вы хотите.

Попробуйте сгруппировать SSN в таблице 2 и получить максимальный код состояния:

SELECT Table1.*, DT.StateCode
FROM Table1
LEFT OUTER JOIN (
    SELECT SSN, MAX(StateCode) AS StateCode FROM Table2 GROUP BY SSN
) DT ON Table1.SSN = DT.SSN

Добавить к комментарию pixelbits. Вы можете выполнить подзапрос с помощью (skip MID)

 select distinct ssn,* from tbl1

И слева присоедините это к tbl2

Это должно дать ваши 50 строк, если только другие столбцы, кроме MID, не отличаются