简体   繁体   中英

Inner Join for 3 tables with SUM of two columns in SQL Query?

I have the following three tables:

表客户

餐桌销售

表 Sales_Payment

I have Following Query to Join Above 3 Tables

     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 

Result for Above Query is given below查询输出

Sum of sales.total is double of the actual sum of sales.total column which has 2-row count, I need to have the actual SUM of that column, without doubling the SUM of those rows, Thank you, for your help in advance..

PROBLEM

The problem here is that there are consecutive inner joins and the number of rows getting fetched in the second inner join is not restricted. So, as we have not added a condition on sales_payment_id in the join between the sales and sales_payment tables, one row in sales table(for customer_id 2, in this case) would be mapped to 2 rows in the payment table. This causes the same values to be reconsidered. In other words, the mapping for customer_id 2 between the 3 tables is 1:1:2 rather than 1:1:1.

SOLUTION

Solution 1: As mentioned by Gordon, you could first aggregate the amount values of the sales_payments table and then aggregate the values in sales table.

Solution 2: Alternatively (IMHO a better approach), you could add a foreign key between sales and sales_payment tables. For example, the sales_payment_id column of sales_payment table can be introduced in the sales table as well. This would facilitate the join between these tables and reduce additional overheads while querying data.

The query would then look like:

`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 ;`

Hope that helps!

You have multiple rows for sales_payments and sales per customer. You need to pre-aggregate to get the right value:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM