Внутреннее объединение для 3 таблиц с суммой двух столбцов в SQL Запрос? - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть следующие три таблицы:

Table Customer

Table Sales

Table Sales_Payment

У меня есть следующий запрос для объединения трех таблиц

     customer.customer_id,
     customer.name,
     SUM(sales.total),
     sales.created_at,
     SUM(sales_payments.amount)
FROM
     sales INNER JOIN customer ON customer.customer_id = sales.customer_id
     INNER JOIN sales_payments ON sales.customer_id = sales_payments.customer_id
WHERE sales.created_at ='2020-04-03'
GROUP By customer.name 

Результат для указанного выше запроса приведен ниже Query Output

Сумма sales.total - это двойная сумма от фактической суммы столбца sales.total, в котором есть счет в 2 строки. Мне нужно иметь фактическую сумму этого столбца, не удваивая сумму этих строк. Спасибо за помощь в заранее ..

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

ПРОБЛЕМА

Проблема здесь в том, что существуют последовательные внутренние объединения, и число строк, извлекаемых во втором внутреннем соединении, не ограничено. Таким образом, поскольку мы не добавили условие для sales_payment_id в объединении между таблицами sales и sales_payment, одна строка в таблице продаж (в данном случае для customer_id 2) будет сопоставлена ​​с 2 строками в таблице платежей. Это вызывает пересмотр одних и тех же значений. Другими словами, отображение для customer_id 2 между 3 таблицами составляет 1: 1: 2, а не 1: 1: 1.

РЕШЕНИЕ

Решение 1: Как упомянутый Гордоном, вы могли бы сначала агрегировать значения сумм в таблице sales_payments, а затем агрегировать значения в таблице продаж.

Решение 2. В качестве альтернативы (ИМХО лучший подход), вы можете добавить внешний ключ между продажами и таблицы оплаты. Например, столбец sales_payment_id таблицы sales_payment также может быть введен в таблицу продаж. Это облегчит объединение этих таблиц и уменьшит дополнительные издержки при запросе данных.

Запрос будет выглядеть следующим образом:

`SELECT c.customer_id,
  c.name,
  SUM(s.total),
  s.created_at,
  SUM(sp.amount)
FROM customer c
INNER JOIN sales s
ON c.customer_id = s.customer_id
INNER JOIN sales_payments sp
ON c.customer_id        = sp.customer_id
AND s.sales_payments_id = sp.sales_payments_id
WHERE s.created_at      ='2020-04-03'
GROUP BY c.customer_id,
c.name,
s.created_at ;`

Надеюсь, это поможет!

1 голос
/ 03 апреля 2020

У вас есть несколько строк для sales_payments и sales для каждого клиента. Вам нужно предварительно агрегировать, чтобы получить правильное значение:

SELECT c.customer_id, c.name, s.created_at, s.total, sp.amount
FROM customer c JOIN
     (SELECT s.customer_id, s.created_at, SUM(s.total) as total
      FROM sales s
      WHERE s.created_at ='2020-04-03'
      GROUP BY s.customer_id, s.created_at
     ) s
     ON c.customer_id = s.customer_id JOIN
     (SELECT sp.customer_id, SUM(sp.amount) as amount
      FROM sales_payments sp
      GROUP BY sp.customer_id
     ) sp
     ON s.customer_id = sp.customer_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...