Oracle - объединить несколько столбцов, пробуя разные комбинации - PullRequest
0 голосов
/ 27 марта 2020

Я попытаюсь объяснить мою проблему: мне нужно найти наиболее эффективный способ объединения двух таблиц на 4 столбца, но данные действительно бесполезны, поэтому могут быть случаи, когда я могу объединить только 3 или 2 столбца, потому что четвертый и / или третий хранились плохо (с пробелами, нулями, тире, ...) Я должен попытаться добиться чего-то вроде этого:

select * from table a
join table b
on a.key1=b.key1
and a.key2=b.key2
or a.key3=b.key3
or a.key4=b.key4```

Я уже выполнил некоторое качество данных, но количество записей действительно высокий (таблица a составляет 300 тыс. записей, а таблица b - около 25 млн. записей). Я знаю, что приведенный мною пример неэффективен, и было бы лучше сделать отдельные объединения, а затем объединить их, но я спрашиваю вас, можно ли найти лучший способ сделать это. Заранее спасибо

1 Ответ

0 голосов
/ 27 марта 2020

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

  1. Есть таблица клиентов и таблица заказов. Оба не связаны через ключи, потому что оба импортированы из разных систем. Теперь ваша задача - найти клиента по заказу.
  2. Обе таблицы содержат фамилию, имя, город и номер клиента. Однако эти столбцы являются необязательными в таблице заказа (но всегда указываются либо фамилия, либо номер клиента). И иногда имя или город могут быть сокращены или написаны с ошибками (например, J./James, NY / New York, Cris / Chris).

Итак, если заказ содержит номер клиента, мы имеем матч и готово. В противном случае фамилия должна совпадать. В последнем случае мы смотрим на имя и город тоже. У обоих совпадают? Единственный? Не так ли?

Мы используем RANK, чтобы ранжировать клиентов по заказу и выбирать лучшие совпадения. Некоторые заказы будут заканчиваться ровно одним совпадением, другие будут иметь связи, и мы должны затем проверить данные вручную (наихудший случай - отсутствие номера клиента и совпадения фамилии из-за имени с ошибкой).

select *
from
(
  select
    o.*,
    c.*,
    rank() over 
    (
      partition by o.order_number
      order by 
      case
        when c.client_number = o.client_number then 1
        when c.last_name = o.last_name and c.first_name = o.first_name and c.city = o.city then 2
        when c.last_name = o.last_name and (c.first_name = o.first_name or c.city = o.city) then 3
        when c.last_name = o.last_name then 4
        else 5
      end
    ) as rnk
  from orders o
  left join clients c on c.client_number = o.client_number or c.last_name = o.last_name
) ranked
where rnk = 1
order by order_number;

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

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