Удаление дубликатов из SQL Join - PullRequest
18 голосов
/ 17 августа 2011

Ниже приведены гипотетические ситуации, которые близки к моей реальной проблеме.Table1

recid   firstname    lastname   company
1       A             B          AAA
2       D             E          DEF
3       G             H          IJK
4       A             B          ABC

У меня есть таблица2, которая выглядит следующим образом

recid   firstname    lastname   company
10      A             B          ABC
20      D             E          DEF
30      M             D          DIM
40      A             B          CCC

Теперь, если я присоединюсь к таблице по recid, это даст 0 результатов, дубликатов не будет, потому что recidуникальный.Но если я присоединяюсь к столбцу имени и фамилии, которые не являются уникальными и имеют дубликаты, я получаю дубликаты при внутреннем объединении.Чем больше столбцов я добавляю при объединении, тем хуже становится (создается больше дубликатов).

В приведенной выше простой ситуации как удалить дубликаты в следующем запросе.Я хочу сравнить имя и фамилию, если они совпадают, я возвращаю имя, фамилию и повтор из таблицы 2

select distinct * from
(select recid, first, last from table1) a
inner join
(select recid, first,last from table2) b
on a.first = b.first

Сценарий здесь, если кто-то захочет поиграть с ним в будущем

create table table1 (recid int not null primary key, first varchar(20), last varchar(20), company varchar(20))
create table table2 (recid int not null primary key, first varchar(20), last varchar(20), company varchar(20))

insert into table1 values(1,'A','B','ABC')
insert into table1 values(2,'D','E','DEF')
insert into table1 values(3,'M','N','MNO')
insert into table1 values(4,'A','B','ABC')

insert into table2 values(10,'A','B','ABC')
insert into table2 values(20,'D','E','DEF')
insert into table2 values(30,'Q','R','QRS')
insert into table2 values(40,'A','B','ABC')

Ответы [ 2 ]

20 голосов
/ 17 августа 2011

Вы не хотите делать соединение само по себе, вы просто проверяете наличие / включение набора.

Я не знаю, какой сейчас SQL-код вы используете, но это должно сработать.

SELECT MAX(recid), firstname, lastname 
FROM table2 T2
WHERE EXISTS (SELECT * FROM table1 WHERE firstname = T2.firstame AND lastname = T2.lastname)
GROUP BY lastname, firstname

Если вы хотите реализовать как объединение, оставляя код в основном таким же:

т.е.

SELECT max(t2.recid), t2.firstame, t2.lastname 
FROM Table2 T2 
INNER JOIN Table1 T1 
    ON T2.firstname = t1.firstname and t2.lastname = t1.lastname
GROUP BY t2.firstname, t2.lastname 

В зависимости от СУБД внутреннее объединение может быть реализовано иначе, чем в Exists (полусоединение или объединение), но оптимизатор иногда может все равно выяснить это и выбрать правильный оператор независимо от того, каким образом вы его пишете.

4 голосов
/ 17 августа 2011
SELECT t2.recid, t2.first, t2.last 
FROM  table1 t1
INNER JOIN table2 t2 ON t1.first = t2.first AND t1.last = t2.last
GROUP BY t2.recid, t2.first, t2.last

РЕДАКТИРОВАТЬ: Добавлена ​​картинка

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...