SQL Объединение двух таблиц и удаление дубликатов из двух таблиц, но без потери дубликатов из таблиц itslef - PullRequest
0 голосов
/ 20 июня 2020

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

T1

Name
-----
A
A
B
C

T2

Name
----
A
D
E

Ожидаемый результат

A - > FROM T1
A - > FROM T1
B
C
D
E

Я пробовал union, но удалял все дубликаты 'A' из обеих таблиц.

Как этого добиться?

Ответы [ 6 ]

4 голосов
/ 20 июня 2020

Фильтр T2 перед UNION ALL

select col 
from T1
union all
select col 
from T2 
where not exists (select 1 from T1 where T1.col = T2.col)
2 голосов
/ 20 июня 2020

Предполагая, что вам нужно количество дубликатов из таблицы с наибольшим количеством повторений для каждого значения, вы можете сделать это с помощью функции окна ROW_NUMBER(), чтобы исключить дубликаты по их последовательности с набором повторений в каждой таблице.

SELECT Name FROM (
   SELECT Name, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Name ) AS Row
     FROM T1
   UNION
   SELECT Name, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Name ) AS Row
     FROM T2
) x
ORDER BY Name

Чтобы увидеть, как это работает, мы добавляем две B строки к T2, затем делаем следующее:

SELECT Name, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Name ) AS Row
  FROM T1
Name  Row
A     1
A     2
B     1
C     1

SELECT Name, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Name ) AS Row
  FROM T2
Name  Row
A     1
B     1
B     2
D     1
E     1

Теперь UNION их без ALL для объединения и удаления дубликатов:

SELECT Name, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Name ) AS Row
  FROM T1
UNION
SELECT Name, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Name ) AS Row
  FROM T2
Name  Row
A     1
A     2
B     1
B     2
C     1
D     1
E     1

Последний запрос вверху просто удаляет столбец Row и сортируя результат, чтобы обеспечить порядок возрастания.

См. SQL Fiddle для демонстрации.

1 голос
/ 20 июня 2020
select * from T1
union all 
select * from T2 where name not in (select distinct name from T1)

Sql Fiddle Demo

1 голос
/ 20 июня 2020

вы должны использовать «union all» вместо «union». «union» удаляет другие повторяющиеся записи, в то время как «union all» дает их все.

для вашего результата, поскольку мы отфильтровали пересечения из таблицы 2 в «where», нам не нужно «UNION ALL»

select col1 from t1
union
select col1 from t2 where t2.col1 not in(select t1.col1 from t1)
0 голосов
/ 20 июня 2020

Вам нужны все имена из T1 и все имена из T2, кроме имен из T1. Таким образом, вы можете использовать UNION ALL для 2 случаев и оператор EXCEPT для фильтрации строк T2:

SELECT Name FROM T1
UNION ALL
(
  SELECT Name FROM T2
  EXCEPT
  SELECT Name FROM T1
) 

См. demo . Результатов:

> | Name |
> | :--- |
> | A    |
> | A    |
> | B    |
> | C    |
> | D    |
> | E    |
0 голосов
/ 20 июня 2020

Я не знаю, является ли следующий код хорошей практикой или нет, но он работает

select name from T1 

UNION

select name from T2 Where name not in (select name from T1)

Вышеуказанный запрос Отфильтруйте значение на основе значения T1, а затем объедините значения двух таблиц и покажите результат.

Надеюсь, это вам поможет, спасибо.

Примечание: это не лучший способ получить результат, он влияет на вашу производительность.

Я уверен, что обновлю лучшее решение после моего исследования

...