inner join of four table with mysql - mysql

I have four table.I want the result of inner join of four tables.My query is :
select
customer.id,
customer.name,
customer.opeing_balance,
customer.opening_balance_type,
sum(sale.total) as sum_total,
sum(receipt.net_amount) as sum_net_amount,
sum(sale_return.total_return) as sum_sale_return
from customer
inner join sale on customer.id=sale.cust_id
inner join receipt on customer.id=receipt.cust_id
inner join sale_return on customer.id=sale_return.cust_id
group by customer.id
table structure
customer
id name opening_balance opening_balance_type
26 neena 50 debit
27 shan 50 debit
sale
cust_id total
27 50
27 50
26 60
26 40
receipt
cust_id net_amount
27 10
27 10
26 50
26 10
sale_return
cust_id total_return
27 10
27 20
26 15
26 20
Result
name opening_balance opening_balance_type sum_total sum_net_amount sum_sale_return
neena 50 debit 100 60 35
shan 50 debit 100 20 30
I want the customer_name,opeing_balance,opening_balance_type,sum of total,sum of net_amount,sum of total_retun of each customer.Anybody give any hep?

OK, try this:
select
customer.id,
customer.name,
customer.opeing_balance,
customer.opening_balance_type,
s.total,
r.net_amount,
s_r.total_return
from customer INNER JOIN
(SELECT cust_id,SUM(total) total FROM sale GROUP BY cust_id) s ON s.cust_id = customer.id INNER JOIN
(SELECT cust_id,SUM(net_amount) net_amount FROM receipt GROUP BY cust_id) r ON r.cust_id = customer.id INNER JOIN
(SELECT cust_id,SUM(total_return) total_return FROM sale_return GROUP BY cust_id) s_r ON s_r.cust_id = customer.id
SQLFiddle demo here

you are using aggregate functions, then you should to use group by, but your group by is only over column id
you should to do group by over all columns not included in your aggregate function, it means:
group by customer.id, customer.name, customer.opeing_balance, customer.opening_balance_type
this is your query problem but i don't know it will be solve your problem or not. tell me

please Try This query
select customer.id,customer.name,customer.opeing_balance,customer.opening_balance_type,sum(sale.total) as sum_total,sum(receipt.net_amount) as sum_net_amount, sum(sale_return.total_return) as sum_sale_return from customer as customer inner join sale as sale on customer.id=sale.cust_id inner join receipt as receipt on customer.id=receipt.cust_id inner join sale_return as sale_return on customer.id=sale_return.cust_id group by customer.id

Your sale table doesn't have an id column of its own, so your receipts and returns are associated with a customer but not a specific sale. When you join the tables together, you get the Cartesian product of all the sales with all the receipts and returns. For example, you have a customer:
id name
26 neena
and she has two sales:
cust_id total
26 60
26 40
and she also has two returns:
cust_id total_return
26 15
26 20
and the join of these tables produces:
cust_id total total_return
26 60 15
26 60 20
26 40 15
26 40 20
Notice that each record from sale has been paired with each record from sale_return. This is what database joins do, unless you include join conditions that limit which rows can be paired with which other rows.
You need to add an id column to the sale table and link the receipts and returns to a specific sale instead of just to a customer, so that when you join the tables you can use on sale_return.sale_id = sale.id. And if there can be several receipts for a single sale, you probably need to add an id to receipt as well, and link each return to that instead of to a sale.
Here's a step-by-step look at how the results for Neena are produced:
First, you pull in Neena's record with from customer. (I'm ignoring Shan's record.) Initially you have just one row:
id name
26 neena
Then you join in her sales with inner join sale on customer.id=sale.cust_id. This pairs the single customer row with all sales that have the same customer ID, so now you have two rows:
id name cust_id total
26 neena 26 60
26 neena 26 40
Then you join in her receipts with inner join receipt on customer.id=receipt.cust_id. This pairs each of the two rows above with all the receipts that have the same customer ID, so now you have four rows:
id name cust_id total cust_id net_amount
26 neena 26 60 26 50
26 neena 26 60 26 10
26 neena 26 40 26 50
26 neena 26 40 26 10
Finally you join her returns with inner join sale_return on customer.id=sale_return.cust_id. This pairs each of the four rows with all the returns that have the same customer ID, so now you have eight rows:
id name cust_id total cust_id net_amount cust_id total_return
26 neena 26 60 26 50 26 15
26 neena 26 60 26 50 26 20
26 neena 26 60 26 10 26 15
26 neena 26 60 26 10 26 20
26 neena 26 40 26 50 26 15
26 neena 26 40 26 50 26 20
26 neena 26 40 26 10 26 15
26 neena 26 40 26 10 26 15
These eight rows are the result of your entire from clause, and they're the input to the sum functions. The sum(sale.total) is 60+60+60+60+40+40+40+40, which is 400. The sum(receipt.net_amount) is 50+50+10+10+50+50+10+10, which is 240, and the sum(sale_return.total_return) is 15+20+15+20+15+20+15+20, which is 140.

Related

Calculate the number of users based on the below conditions by writing a single query SQL

There are two campaigns running campaign A and Campaign B and list of user ids participated in those two campaign is given below. Calculate the number of users based on the below conditions by writing a single query.
Participated in campaign A
Participated in campaign B
Participated in campaign A only
Participated in campaign B only
Participated in both the campaigns
Participated in either campaign A or Campaign B
Campaign A Campaign B
user_id user_id
91 62
27 11
58 16
50 92
64 17
65 71
54 12
98 37
78 93
24 58
31 54
73 94
63 85
72 30
94 32
20 1
38 48
8 99
43 45
33 46
26 39
100 29
61 49
87 73
84 81
15 88
80 70
77 33
40 55
82
42
56
95
88
I am not able to figure out how to write in single SQL query.
Assuming you have two different tables, you can use union all and aggregation:
select in_a, in_b, count(*) as num_users
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u
group by in_a, in_b;
This gives you all the information you need. You can use group by in_a, in_b with rollup to get all combinations.
Or, you can summarize this into one row:
select sum(in_a) as in_a, sum(in_b) as in_b,
sum(in_a * (1 - in_b)) as in_a_only,
sum(in_b * (1 - in_a)) as in_b_only,
sum(in_a * in_b) as in_ab
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u;
Note: These both assume that users are unique in each campaign. If not, just use select distinct or union in the subquery.

MySQL seems to ignore my WHERE clause with inner joins

In order to display data (orders or bids) in a excel-like grid, i fetch from my database with the help of this query. In this case, the order_bid table store the lines that compose an order (a line for each item), the item table defines the price of an item, the current sale the item is displayed on, and the lot table defines the item itself (name, description_ect...)
Here is the request i make, orders are another table but the important part is that an order_bid is linked to an order, and orders are linked to a unique sale, but it seems to ignore the WHERE close, so i get a lot more results than expected (for example if a client placed a bid for lot 4 of sale 1, i would see a bid for sale 2 lot 4, and so on for all sales that have a lot number 4 (so all of them basically))
SELECT o.id, o.order_id, o.lot_num, o.bid, i.lot_id, i.sale, i.price, l.description_fr
FROM order_bid o
INNER JOIN item i
ON o.lot_num = i.lot_num
INNER JOIN lot l
ON l.id = i.lot_id
WHERE o.order_id = 38
For example i expect for a request a result like:
id
order_id
lot_num
bid
lot_id
sale
price
description_fr
110
38
17
135
19
sale1
135
description1
111
38
21
83
23
sale1
183
description2
109
38
10
100
790
sale1
100
description3
but i get:
id
order_id
lot_num
bid
lot_id
sale
price
description_fr
110
38
17
135
19
sale1
135
description1
111
38
21
83
23
sale1
183
description2
111
38
21
183
11968
sale11
150
description4
109
38
10
100
790
sale1
100
description3
and a lot of other lots that i shouldn't be getting from other sales
and i verified, when i request all the order_bid with order_id = 38 (SELECT * FROM order_bid WHERE order_id = 38) i get:
id
order_id
lot_num
bid
109
38
10
100
110
38
17
135
111
38
21
183
summarized: i get info from multiple sales when i'm supposed to get only from one (done using the order_id filter)

How to get total appointment durations from this table using sql

I have 3 mysql tables:
appointments
id slot_id patient_name doctor_id deleted_at
1 11 Tasin 23 2019-10-10
2 12 Nawaz 22 null
3 13 Rakib 23 null
4 14 Hossen 23 null
5 15 Aritra 24 null
6 16 Anik 22 null
7 17 Manik 22 null
doctors
id status doctor_name
22 1 Khaled
23 1 Hasan
24 0 Rumi
slots
id date duration time
11 2019-10-10 2900 01:01
12 2019-10-11 1200 02:01
13 2019-10-18 1100 03:01
14 2019-09-08 200 11:01
15 2019-08-01 500 01:31
16 2019-10-07 300 02:31
17 2019-10-02 1200 03:31
Now, I want to show a list of doctors with their total appointment durations in decreasing order using SQL query.
Unfortunately, I don't have any idea about this SQL query. Can you assist me?
SELECT DOCTOR_NAME, SUM(DURATION) FROM APPOINTMENTS A
JOIN DOCTORS D ON D.ID = A.DOCTOR_ID
JOIN SLOTS S ON S.ID = A.SLOT_ID
GROUP BY D.ID, DOCTOR_NAME
ORDER BY SUM(DURATION) DESC;
select d.doctor_id, d.doctor_name, sum(apt.duration) as total_duration from
doctors as d
join appointments as apt on apt.doctor_id = d.doctor_id
join slots as s on s.id = apt.slot_id
group by d.doctor_id, d.doctor_name
The above query should work fine.
There might be some typo as I didn't write it in the SQL management studio.

MySQL get the latest products with distinct product_name from a particular month

I've the following product table in my database. I want to get the rows of all the products with distinct product_name added in the month of Dec in the descending order of their id.
id product_name qty month
1 Apple 20 Dec
2 Banana 40 Jan
3 Cherry 60 Jun
4 Apple 25 Dec
5 Banana 50 Dec
6 Papaya 20 Dec
7 Guava 34 Aug
8 Watermelon 55 Mar
9 Apple 75 Dec
10 Orange 32 Dec
The resulting table should be as below:
id product_name qty month
10 Orange 32 Dec
9 Apple 75 Dec
6 Papaya 20 Dec
5 Banana 50 Dec
So far I've come up with the following query and it doesn't get the result I need.
SELECT *
FROM product
WHERE month = "Dec"
GROUP BY product_name
ORDER BY id DESC
The problem with this query is that it gets the first row/record of Apple rather than last one as shown in table below:
id product_name qty month
10 Orange 32 Dec
6 Papaya 20 Dec
5 Banana 50 Dec
1 Apple 20 Dec
Can anyone help me write a proper mysql query for this?
You can use the following query:
SELECT MAX(id), product_name
FROM product
WHERE month = "Dec"
GROUP BY product_name
to get the biggest id per product_name:
Output:
max_id product_name
9 Apple
5 Banana
10 Orange
6 Papaya
Using the above query as a derived table you can join back to the original table in order to get the rest of the fields:
SELECT t1.*
FROM product AS t1
INNER JOIN (
SELECT MAX(id) AS max_id, product_name
FROM product
WHERE month = "Dec"
GROUP BY product_name
) AS t2 ON t1.id = t2.max_id and t1.product_name = t2.product_name
ORDER BY t1.id
Demo here

How to combine many to many join?

Tables:
cust table:
cust_id, name, etc
bill table:
bill_id, cust_id, amt, due_date, status (open/closed)
payment table:
payment_id, bill_id, amt etc
Customer can settle a single bill by paying multiple installments. So, one bill_id may relate to payment_ids.
I am unable to generate this recordset:
cust_id | due amt
'due amt' is the sum of all bill.amts - sum of all payment.amts and having status open.
Bill table
bill_id cust_id amt status
1 18 200 open
2 18 200 open
3 17 200 open
4 17 200 open
5 17 200 open
6 17 200 closed
Payment table
payment_id bill_id cust_id amt
1 1 18 50
2 2 18 40
3 3 17 10
Expected output
cust_id due_amt hint/how
17 590 (600-10) .. 600 -> because one is closed
18 310 (400-(50+40))
select c.cust_id, sum(b.amt) - sum(p.amt) as due_amt
from cust c
left join bill b on b.cust_id = c.cust_id and b.status = 'open'
left join payment p on p.bill_id = b.bill_id
group by c.cust_id
SQLFiddle demo