2013-08-15 2 views
4

У меня проблема, когда я пытаюсь найти людей, у которых есть старые учетные записи с непогашенным балансом, но которые создали новую учетную запись. Мне нужно сопоставить их, сравнивая SSN. Проблема в том, что у нас есть первичные и дополнительные контакты, поэтому 2 потенциальных SSN для каждой учетной записи. Мне нужно сопоставить его, даже если они сначала первичны, но теперь являются вторичными и т. Д.SQL-запрос с несколькими возможными объединениями (или условие в соединении)

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

select count(*) 
from personal pa 
join consumer c 
on c.cust_nbr = pa.cust_nbr 
and c.per_acct = pa.acct 
join personal pu 
on pu.ssn = pa.ssn 
or pu.ssn = pa.addl_ssn 
or pu.addl_ssn = pa.ssn 
or pu.addl_ssn = pa.addl_ssn 
join uncol_acct u 
on u.cust_nbr = pu.cust_nbr 
and u.per_acct = pu.acct 
where u.curr_bal > 0 

Это работает, но требуется 20 минут для запуска. Я нашел этот вопрос Is having an 'OR' in an INNER JOIN condition a bad idea?, поэтому я попробовал переписать его в виде 4 запросов (по одному на комбинацию ssn) и объединить их. Это заняло 30 минут.

Есть ли лучший способ сделать это, или это просто очень неэффективный процесс, не так ли, как вы это делаете?

Обновление: После игры с некоторыми вариантами здесь и некоторыми другими экспериментами, я думаю, что нашел проблему. Наш поставщик программного обеспечения шифрует SSN в базе данных и предоставляет представление, которое расшифровывает их. Поскольку мне приходится работать с этой точки зрения, для дешифрования и последующего сравнения требуется очень долгое время.

+3

Как индексируются таблицы? Вы можете получить значительное ускорение, если индексируете по ssn и addl_ssn (отдельные индексы для каждого) – SWeko

+0

Базу данных управляет наш поставщик программного обеспечения. Я не уверен, как индексирование настроено, или если бы я мог их изменить. Я мог проверить это. – Mike

ответ

2

Если вы запускаете отдельные объединения, а затем объединяете, тогда у вас могут быть проблемы. Что делать, если одна и та же пара записей выполняет по крайней мере два условия? Тогда у вас будут дубликаты в вашем результате.

Я считаю, что ваш первый подход возможен, но не забывайте, что вы соединяете четыре таблицы. Если число строк равно A, B, C, D в соответствующих таблицах, тогда RDBMS должна будет проверить максимум записей A * B * C * D. Если у вас много записей в вашей базе данных, это займет много времени.

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

Кроме того, если вы присоединяетесь четыре таблицы, личные, потребительские, личные (снова) и uncol_acct, то вы могли бы сделать что-то вроде этого:

Напишите запрос, который содержит два подзапроса, каждый из которых назван t1 и t2 соответственно. Первый подзапрос соединяется с персональным и потребительским и будет называть результат t1. Второй запрос присоединяется ко второму вхождению персонажа с помощью uncol_acct, а предложение where будет внутри вашего второго соединения. Как описано выше, ваш запрос будет содержать два подзапроса, названных t1 и t2, соответственно. Ваш запрос присоединится к t1 и t2. Таким образом, вы опишете, так как ваш основной запрос будет рассматривать только пару правильных t1 и t2.

Кроме того, если предложение where находится снаружи, как в вашем примере запроса, тогда будет выполняться 4-мерное соединение, и только после этого будет учитываться то, что будет принято во внимание. Вот почему предложение where должно быть внутри второго подзапроса, поэтому предложение where будет выполняться до основного соединения. Кроме того, вы можете создать подзапрос во втором подзапросе, чтобы вычислить, где, если условие выполняется редко.

Cheers!

+0

Индексирование осуществляется нашим поставщиком программного обеспечения, и я не знаю, могу ли я их изменить или нет. Это редкая процедура, а не чувствительность к времени, поэтому, вероятно, этого не стоит. Мне нравится идея с двумя подзапросами, я посмотрю, будет ли она быстрее. Что касается дублирующих записей, я не думаю, что это происходит, потому что мои подсчеты одинаковы для обоих методов. Также в этом случае было бы не очень важно, потому что кто-то будет перебирать список, чтобы попытаться отследить людей. Если они появятся дважды, все в порядке. – Mike

+0

+1 для «информационного» ответа –

+0

Дублированные записи будут происходить в случае, когда вы объединяетесь в том и только в том случае, если существует хотя бы пара, где выполняется более одного условия соединения. Вы можете предотвратить это, используя различное ключевое слово. Тем не менее, решение, предложенное в моем ответе, предотвращает это, потому что запросы не разбиваются на разделы, только соединения переформатируются с использованием подзапросов, чтобы ускорить работу. –

Смежные вопросы