How to join 3 table with this condition? - mysql

I have 3 tables: product, customer and transaction.
Product:
id_product price
1 1000
2 2000
Customer:
id_customer name
1 Tom
2 Jack
Transaction:
id_transaction id_product id_customer qty date
1 1 1 10 2013-02-21
2 2 1 50 2013-02-21
3 1 2 15 2013-02-21
I want to achieve this result:
id_customer name total_transaction purchase_qty subtotal
1 Tom 2 60 110000
2 Jack 1 15 15000
How I can get that result using a query in MySQL?

SELECT t.id_customer, c.name,
COUNT(t.id_customer) AS total_transaction,
SUM(t.qty) as purchase_qty
FROM transaction t
INNER JOIN customer c
ON t.id_customer = c.id_customer
GROUP BY t.id_customer,c.name

SELECT cs.id_customer, cs.name, COUNT(tr.transaction) AS total_transaction, SUM(tr.qty) as purchase_qty, SUM(tr.qty*pr.prize)
FROM customer AS cs
LEFT JOIN transaction AS tr ON tr.id_customer = cs.id_customer
LEFT JOIN product AS pr ON pr.id_product = tr.id_product
GROUP BY cs.id_customer
I suppose you are a total beginner, so I did this for you. Next time, if you have ANY own ideas, give to us, so we don't have to write the whole query for you. Show some effort.

SELECT c.id_customer, c.name, count(t.id_transaction) AS total_transaction
FORM Customer c INNER JOIN Transaction T
ON C.id_customer = T.id_customer
GROUP BY c.id_customer

You need a group by statement since you want to aggregate results for a given customer :
SELECT id_customer, name, count(id_transaction) AS total_transaction
FORM Customer, Transaction
WHERE Transaction.id_customer = Customer.id_customer
GROUP BY id_customer
This does not solve your whole problem, but you've got the idea.

Related

How to group rows in SQL by earliest date when are there are multiple rows with earliest date?

I am trying to come up with a query that will return the aggregate data for the earliest orders the customers have placed. What I cannot quite wrap my head around is how to construct this query when there are multiple orders placed on the same day for the earliest purchase date for customer 2.
customers
id
name
created_at
1
Sam
2019-07-12
2
Jimmy
2019-01-22
items
id
name
price
1
Watch
200
2
Belt
75
3
Wallet
150
orders
id
customer_id
item_id
created_at
1
1
1
2018-08-01
2
1
2
2018-08-11
3
2
1
2019-01-22
4
2
3
2019-01-22
5
2
2
2019-03-03
expected query
customer_id
name
first_purchase_date
n_items
total_price
1
Sam
2018-08-01
1
200
2
Jimmy
2019-01-22
2
350
I currently have the following query set up, but this query is grouping by the customer_id such that the total number of items and total price do not reflect the earliest orders.
SELECT
orders.customer_id,
customers.name AS name,
MIN(orders.created_at) AS first_purchase_date,
COUNT(*) as n_items,
SUM(items.price) as total_price
FROM orders
INNER JOIN customers
ON orders.customer_id = customers.id
INNER JOIN items
ON orders.item_id = items.id
GROUP BY
customers.id
my incorrect query
customer_id
name
first_purchase_date
n_items
total_price
1
Sam
2018-08-01
2
275
2
Jimmy
2019-01-22
3
425
I recreated the tables in a SQL Server environment but this should help...I hope as it gives you the query result you're looking for. The data is exactly the same but I'm using temporary tables so hence the # prefixes.
SELECT
#orders.customer_id,
#customer.name AS name,
#orders.created_at as first_purchase_date,
--MIN(#orders.created_at) AS first_purchase_date,
COUNT(*) as n_items,
SUM(#items.price) as total_price
FROM #orders
INNER JOIN #customer
ON #orders.customer_id = #customer.id
INNER JOIN #items
ON #orders.item_id = #items.id
inner join
(
select customer_id, name, MIN(first_purchase_date) as
first_purchase_date
from
(
SELECT
#orders.customer_id,
#customer.name AS name,
#orders.created_at as first_purchase_date,
--MIN(#orders.created_at) AS first_purchase_date,
COUNT(*) as n_items,
SUM(#items.price) as total_price
FROM #orders
INNER JOIN #customer
ON #orders.customer_id = #customer.id
INNER JOIN #items
ON #orders.item_id = #items.id
group by #orders.customer_id,#customer.name, #orders.created_at
)base
group by customer_id, name
) firstorders
on
#customer.id = firstorders.customer_id
and
#customer.name = firstorders.name
and
#orders.created_at = firstorders.first_purchase_date
group by
#orders.customer_id,#customer.name, #orders.created_at

SQL left join two times

The user table looks like this:
user_id
name
surname
1
a
aa
2
b
bb
3
c
cc
The book's table looks like this:
user_id
book_name
1
book1
1
book2
1
book3
2
book1
The expenses table looks like this:
user_id
amount_spent
date
1
10
2020-02-03
1
30
2020-02-02
1
10
2020-02-01
1
15
2020-01-31
1
13
2020-01-15
2
15
2020-02-01
3
20
2020-02-01
The result which I want:
CountUsers
amount_spent
2
65
Explanation: I want to count how many users have book1 and how much total they spend on a date between 2020-02-01 - 2020-02-03.
Now how the query should look like?
I am using MySQL version 8.
I have tried:
SELECT
count(*), sum(amount_spend) as total_amount_spend
FROM
(select sum(amount_spend) as amount_spend
FROM expanses
LEFT JOIN books ON books.user_id = expanses.user_id WHERE books.book_name ='book1 GROUP BY expanses.user_id) src'
And the result is wrong because I am getting a higher amount_spend than in my table result above. I think while joining the table there are some duplicates but I do not know how to fix them.
I want to count how many users have book1 and how much total they spend on a date between 2020-02-01 - 2020-02-03.
I am thinking:
select count(*), sum(e.amount_spent)
from user_books ub join
expenses e
on ub.user_id = e.user_id
where book_name = 'book1';
Note: This assumes that user_books doesn't have duplicate rows.
FIDDLE
You miss the date part in your code.
SELECT
count(*), sum(amount_spent) as total_amount_spend
FROM
(select sum(amount_spent) as amount_spent
FROM expanses
LEFT JOIN books ON books.user_id = expanses.user_id
WHERE books.book_name ='book1'
and expanses.date between '2020-02-01' and '2020-02-03'
GROUP BY expanses.user_id) src;
will do a job.
Please note that you don't need to have left join here (unless you're sure that it may happen that no expenses at all for given user will be), and you don't need to have grouping in subquery. So your query could look like:
select count(distinct expanses.user_id), sum(amount_spent) as amount_spent
from expanses
inner join books on books.user_id = expanses.user_id
where books.book_name ='book1'
and expanses.date between '2020-02-01' and '2020-02-03';

SUM, GROUP BY AND LEFT JOIN in query

I've two tables:
`orders`
order_id order_office_id order_invoice_id
1 1 1
2 2 2
3 2 2
4 2 3
5 1 4
`invoices`
inv_id inv_order_id inv_amount
1 1 500.00
2 0 320.00
3 3 740.00
4 4 160.00
With this query:
SELECT SUM(inv_amount) matrah, order_office_id
FROM `invoices`
LEFT JOIN orders ON order_invoice_id = inv_id OR inv_order_id = order_id
WHERE order_id IS NOT NULL
GROUP BY order_office_id
It is multiplying some amounts.
What I want to get sum of amounts by office:
office_id sum
1 660.00
2 1060.00
How to get proper amounts by single query?
This does what you want, I think
select sum(inv_amount) as matrah,
(select order_office_id from orders where order_invoice_id = inv_id limit 1) as office
from invoices
group by office;
I've removed the OR, because you were getting two office ids for one of the orders, so it was ambiguous. I've included a subquery to make sure that only one office is applied to each order.
This query may help you out:
SELECT SUM(i.inv_amount) matrah, o.order_office_id
FROM `invoices` AS i
LEFT JOIN `orders` AS o
ON o.order_invoice_id = i.inv_id
GROUP BY order_office_id
OR statement in your ON condition caused the problem.

How to get right sum from inner join in mysql

I have two tables one is orders and second is order_product in which I have to find out orders count, product count, totalamount in corresponding to store using store id from which I have successfully find out the orders count and product count but my totalamount is not coming correct.
orders:
...........................
order_id or_total_amt
...........................
1 10
2 10
3 10
order_product
.................................
op_id op_order_id st_id
.................................
1 1 1
2 2 2
3 3 1
4 3 1
I want below output but my totalamount value is coming wrong it is coming 30,but the correct value is 20 which i have mentioned in the right output below.
output which i want:
.........................................
st_id orders product totalmount
.........................................
1 2 3 20
2 1 1 10
I have tried the below query which is giving 30 value of totalamount which is wrong.
SELECT `op_st_id`,count(distinct orders.`order_id`)as orders,count(order_product.op_pr_id) as product
,sum(orders.or_total_amt) as totalamount from orders
inner JOIN order_product on orders.order_id=order_product.op_order_id
group by `op_st_id`
SELECT
`st_id`,
count(DISTINCT orders.`order_id`) AS orders,
count(order_product.op_id) AS product,
count(DISTINCT orders.`order_id`)*(sum(orders.or_total_amt)/count(order_product.op_id)) AS totalamount
FROM
orders
INNER JOIN order_product ON orders.order_id = order_product.op_order_id
GROUP BY
`st_id`

how to mysql join for two tables

I have two mysql tables:
table-1: advance
id advance_id vamount
1 101 10000
2 101 20000
3 101 10000
table-2: purchase
id advance_id item amount
1 101 Shirt 500
2 101 Pant 700
3 101 Pen 500
4 101 Shoe 1000
What I want to do, sum of vamount against each advance_id from table-1 and purchase information from table-2 against same advance_id. While trying by the following query:
SELECT sum(a.vamount) as vamount, p.item, p.amount FROM advance as a INNER JOIN purchase as p ON a.advance_id=p.advance_id WHERE p.advance_id=101
I want to fetch the result in this way:
Total Advance Amount: 40000
item amount balance
shirt 500 39500
pant 700 38800
pen 500 38300
shoe 1000 37300
but it is returning one one row in result set.
How to do it in right way?
Try:
SELECT p.item, sum(a.vamount) as vamount, p.amount FROM advance as a INNER JOIN purchase as p ON a.advance_id=p.advance_id WHERE p.advance_id=101
group by p.item
You query should like this
SELECT sum(a.vamount) as vamount
, p.item
, p.amount
FROM advance as a
INNER JOIN purchase as p ON a.advance_id = p.advance_id
WHERE p.advance_id=101
GROUP BY p.item
, p.amount
Use GROUP BY clause and optional you can remove WHERE clause for group all items