Лучший дизайн для устранения дубликатов после запроса объединения - PullRequest
1 голос
/ 09 мая 2019

Я разрабатываю запрос UNION для объединения двух таблиц с информацией о клиентах в базе данных Oracle 11g.Первая таблица a является «основным» источником, вторая таблица b является дополнительным источником с новыми и дублированными записями.

Дубликатыв b невозможно устранить с помощью UNION на самом деле неравных полей, таких как автоинкрементный идентификатор, который необходимо выбрать.

Таблица a

ID CUSTOMER_NUMBER NAME STREET 1 4711 Dirk Downstreet 4 2 4721 Hans Mainstreet 5

Таблица b

ID CUSTOMER_NUMBER NAME STREET 44 4711 Dirk Downstreet 4 <== Duplicate 4 4741 Harry Crossroad 9 <== new

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

ID CUSTOMER_NUMBER NAME STREET DATASOURCE 1 4711 Dirk Downstreet 4 SAP <== from a 2 4721 Hans Mainstreet 5 SAP <== from a 4 4741 Harry Crossroad 9 MANUAL <== from b

Я очень доволен следующей - упрощенной - пробной версией:

SELECT CUSTOMER_NUMBER, 
    MAX(ID) KEEP (DENSE_RANK FIRST ORDER BY DATASOURCE DESC) ID,
    MAX(NAME) KEEP (DENSE_RANK FIRST ORDER BY DATASOURCE DESC) NAME,
    MAX(STREET) KEEP (DENSE_RANK FIRST ORDER BY DATASOURCE DESC) STREET,
FROM 
    (SELECT "ID","CUSTOMER_NUMBER","NAME","STREET", 'SAP' as DATASOURCE FROM CUSTOMERS
        UNION ALL
    SELECT "ID","CUSTOMER_NUMBER","NAME","STREET", 'MANUAL' as DATASOURCE FROM CUSTOMERS_MANUAL) united
group by CUSTOMER_NUMBER

Но у меня естьВЫБЕРИТЕ каждое поле с помощью DENSE_RANK FIRST ORDER BY DATASOURCE DESC, которые составляют около 20 полей ...

Кто-нибудь может показать мне лучший подход?

1 Ответ

2 голосов
/ 09 мая 2019

Альтернативой KEEP для каждого столбца является использование ROW_NUMBER с разделением по вашему уникальному ключу и порядку проставления и выбор только строки с номером 1.

Пример для CUSTOMER_NUMBER какуникальный ключ, предпочитая MANUAL над SAP и ожидая, что ID уникален в каждом источнике.:

SELECT * FROM 
(
SELECT 
   "ID","CUSTOMER_NUMBER","NAME","STREET",
   roww_number() over (partition by CUSTOMER_NUMBER order by decode(DATASOURCE,'SAP',2,'MANUAL',1), ID) as RN
FROM 
    (SELECT   "ID","CUSTOMER_NUMBER","NAME","STREET", 'SAP' as DATASOURCE FROM CUSTOMERS
        UNION ALL
     SELECT   "ID","CUSTOMER_NUMBER","NAME","STREET", 'MANUAL' as DATASOURCE FROM CUSTOMERS_MANUAL) united
) WHERE RN = 1

Это прекрасно работает, даже если отдельные источники доставляют дубликаты.Настройте столбцы порядка так, чтобы запрос оставался детерминированным, т.е. повторный запрос дает тот же результат (например, добавьте NAME, если столбец ID может быть дублирован в SAP)

...