3 таблицы, левое внешнее соединение, SUM - PullRequest
0 голосов
/ 06 февраля 2009

У меня проблема с моим LEFT OUTER JOIN для 3 таблиц с предложением SUM. Это мой код:

SELECT r.ret_desc, vmp.vlt_id,  
SUM((vmp.cash_in + vmp.per_cash_in_sec)
  + (CASE WHEN vmp.acc_id = t.db_id AND t.txn_type_id = 1 THEN t.amount ELSE 0 END)
  - (CASE WHEN vmp.acc_id = t.cr_id AND t.txn_type_id = 1 THEN t.amount ELSE 0 END)) AS in_adj, 

FROM ret AS r
LEFT OUTER JOIN vmp ON r.acc_id = vmp.acc_id
LEFT OUTER JOIN txn AS t ON (r.acc_id = t.credit_acc_id OR r.acc_id = t.debit_acc_id) 

WHERE t.txn_type_id IN (1,2,4,5)
GROUP BY r.ret_desc, vmp.vlt_id
;

Проблема в том, что существует несколько записей VMP, а поле SUM умножается на COUNT записей VMP. Пример: Если поле SUM должно равняться 100 долларам, а записей VMP 50, тогда сумма равна 5000 долларам, тогда как она должна составлять всего 100 долларов. Кто-нибудь знает, что не так с этим утверждением?

Ответы [ 3 ]

1 голос
/ 06 февраля 2009

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

Таким образом, если у вас есть несколько записей txn и vmp для одной записи ret, вы получите количество записей count (txn) * count (vmp) за такт, создавая сумму count (vmp) * txn.amount и count ( txn) * vmp.amount.

Я думаю, что наилучшим решением является внешнее объединение с двумя подвыборками или создание представлений для vmp и txn, которые группируют и суммируют за рет, и внешнее объединение их.

1 голос
/ 06 февраля 2009

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

Есть несколько проблем с тем, что вы делаете, но сначала, если бы я был вами, я бы вычел сумму и посмотрел, что это за расчет, прежде чем подвести итог. В действительности я бы сделал что-то вроде:

SELECT r.ret_desc, vmp.vlt_id,  
(vmp.cash_in + vmp.per_cash_in_sec)  
 + (CASE WHEN vmp.acc_id = t.db_id AND t.txn_type_id = 1 THEN t.amount ELSE 0 END) 
 - (CASE WHEN vmp.acc_id = t.cr_id AND t.txn_type_id = 1 THEN t.amount ELSE 0 END),
vmp.cash_in,vmp.per_cash_in_sec, vmp.per_cash_in_sec,  t.db_id,t.cr_id,         t.txn_type_id ,t.amount
FROM ret AS r
LEFT OUTER JOIN vmp ON r.acc_id = vmp.acc_id
LEFT OUTER JOIN txn AS t ON (r.acc_id = t.credit_acc_id OR r.acc_id = t.debit_acc_id) 
WHERE t.txn_type_id IN (1,2,4,5)

GROUP BY r.ret_desc, vmp.vlt_id

Во-вторых, почему вы делаете левые соединения? Определенно, txn не является левым соединением, поскольку вы использовали его в предложении wher, которое эффективно преобразует его во внутреннее соединение, поэтому, если вам нужно, чтобы оно было левым соединением, вам нужно вместо этого переместить это условие where в предложение on.

0 голосов
/ 06 февраля 2009

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

(1) Таблица RET имеет ACC_ID в качестве первичного ключа
(2) Таблица VMP имеет (ACC_ID, VLT_ID) в качестве своего первичного ключа - поэтому, когда вы говорите «имеется 50 записей VMP», вы имеете в виду 50 записей с тем же ACC_ID, но разными VLT_ID.

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

Описания макетов таблиц и некоторые примеры данных помогут.

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