Лучший способ объединить две таблицы * включая * дубликаты из одной таблицы - PullRequest
0 голосов
/ 16 ноября 2011

Счета (таблица)

+----+----------+----------+-------+
| id | account# | supplier | RepID |
+----+----------+----------+-------+
|  1 | 123xyz   | Boston   |     2 |
|  2 | 245xyz   | Chicago  |     2 |
|  3 | 425xyz   | Chicago  |     3 |
+----+----------+----------+-------+

PayOut (таблица)

+----+----------+----------+-------------+--------+
| id | account# | supplier | datecreated | Amount |
+----+----------+----------+-------------+--------+
|  5 | 245xyz   | Chicago  | 01-15-2009  | 25     |
|  6 | 123xyz   | Boston   | 10-15-2011  | 50     |
|  7 | 123xyz   | Boston   | 10-15-2011  | -50    |
|  8 | 123xyz   | Boston   | 10-15-2011  | 50     |
|  9 | 425xyz   | Chicago  | 10-15-2011  | 100    |
+----+----------+----------+-------------+--------+

У меня есть таблица счетов и таблица выплат.Таблица выплат поступает из-за рубежа, поэтому мы не контролируем ее.Это оставляет нам проблему с тем, что мы не можем объединить две таблицы на основе поля идентификатора записи, это одна проблема, которую мы не можем решить.Поэтому мы присоединяемся на основании номера счета, ID поставщика (2-й и 3-й столбцы).Это создает проблему, которая создает (возможно) отношения многих ко многим.Но мы фильтруем наши записи, если они активны, и используем второй фильтр в таблице выплат при создании выплаты.Выплаты создаются от месяца к месяцу.На мой взгляд, с этим связаны две проблемы

  1. Выполнение запроса занимает довольно много времени (может быть неэффективным)
  2. Существуют определенные дубликаты, которые не следует удалятьудален.Примером являются записи 6 и 8 в таблице выплат.Здесь произошло то, что мы получили клиента, затем клиент отменил его, и он вернул его.В этом случае +50, -50 и +50.Опять же, все значения действительны и должны отображаться в отчете для целей аудита.В настоящее время отображается только один +50, другой потерян.Есть несколько других проблем в отчете, которые появляются время от времени.

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

Вот наш текущий запрос

/* Supplied  to Store Procedure */
-----------------------------------
@RepID // the person for whome payout is calculated
@Month // of payment date
@year  // year of payment date
-----------------------------------
select distinct 
A.col1, 
A.col2,
...
A.col10, 
B.col2, 
B.Col2, 
B.Amount /* this is the important column, portion of which goes to Rep */
from records A
JOIN payout B 
on A.Supplier = B.Supplier AND A.Account# = B.Account#
where datepart(mm, B.datecreated) = @Month /* parameter to stored procedure */
  and datepart(yyyy, B.datecreated) = @Year
  and A.[rep ID] = @RepID /* parameter to SP */
group by
col1,col2,col3,....col10
order by customerName

Является ли этот запрос оптимальным?Могу ли я улучшить его, используя CROSS APPLY или WHERE EXIST, которые сделают его быстрее, а также устранят проблему дублирования?

Обратите внимание, что этот запрос используется для получения выплаты за повторение.Следовательно, каждая запись имеет поле repid, которому она назначена.В идеале я хотел бы использовать запрос Select WHERE Exist.

1 Ответ

0 голосов
/ 16 ноября 2011

Трудно понять, что именно вы хотите, потому что в одном месте вы говорите, что «хотите» дубликаты, но затем вы говорите, что используете группу для удаления дубликатов.Поэтому первой мыслью было бы «Почему бы просто не избавиться от группы?».Но я должен верить, что вы достаточно умны, чтобы думать об этом сами, поэтому я полагаю, что это должно быть по какой-то причине., но поскольку вы говорите, что не можете, я просто попытаюсь дать вам какое-то руководство в решении проблемы ...

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

...