distinct records sum when joining different tables in mysql - mysql

Table : O
ID Date
1 2016-01-10
2 2016-01-10
3 2016-01-11
Table : OD
ODI ID Quantity
1 1 1
2 1 2
3 2 1
4 3 1
Table: OH
OHI ID
1 1
2 2
3 1
4 3
I have three table O,OD,OH. I need to join these three table and get the sum of quantity For each day.
Tried
SELECT O.date,SUM(od.Quantity),group_concat(OHI) FROM O
INNER JOIN OD ON OD.ID = O.ID
INNER JOIN OH ON OH.ID = O.ID
GROUP BY O.date;
But the resulting quantity sum was different due to joining the OH Table.Now How do i get the proper Sum.
Expected Result :
Date SUM(od.Quantity)
2016-01-10 4
2016-01-10 1
Sorry For Change In The Question.

You don't need to join OH table, this can be done with below query:
SELECT O.ID,SUM(od.Quantity) FROM O
INNER JOIN OD ON OD.ID = O.ID
GROUP BY O.ID;

You don't need to join with the OH table.
select O.ID, SUM(OD.Quantity) total_qty
from O inner join OD
on O.ID = OD.ID
group by O.ID;
If you need join with OH, then do it after aggregation.
select *
from OH inner join (
select O.ID, SUM(OD.Quantity) total_qty
from O inner join OD
on O.ID = OD.ID
group by O.ID
) t on t.ID = OH.ID;

Aggregate over the OD table first in a subquery, then join this to the other two tables:
SELECT t1.Date,
t2.Quantity,
t3.OHI -- and possibly other columns from OH
FROM O t1
INNER JOIN
(
SELECT ID, SUM(Quantity) AS Quantity
FROM OD
GROUP BY ID
) t2
ON t1.ID = t2.ID
INNER JOIN OH t3
ON t1.ID = t3.ID

Related

SQL to group and sum subitem and parent rows

I'm having issues trying to figure out how to group and sum subitem with parent item rows.
I have a SQL query that looks like this:
select
topics.name,
sum(commission_amount) as commission
from orders
left join topics
on topics.id = orders.topic_id
group by 1
This works, however I'm trying to group and use only parent topic names.
Topics table:
id
name
topic_id
1
Meal Delivery
NULL
2
Vegan Meal Delivery
1
3
Vegetarian Meal Delivery
1
4
Mattresses
NULL
5
Hybrid Mattress
4
6
Memory Foam Mattress
4
So a parent topic is when topic_id = NULL
Orders table:
id
topic_id
commission_amount
1
1
10
2
2
20
3
3
30
4
4
40
5
5
50
6
6
60
Desired output is this:
name
commission
Meal Delivery
60
Mattresses
150
Join with topics again.
SELECT name, SUM(commission) AS commission
FROM (
-- subtopic commissions
SELECT t1.name, IFNULL(SUM(o.commission_amount), 0) AS commission
FROM topics AS t1
LEFT JOIN topics AS t2 ON t1.id = t2.topic_id
LEFT JOIN orders AS o ON o.topic_id = t2.id
WHERE t1.topic_id IS NULL -- only show parent topics
GROUP BY t1.name
UNION ALL
-- parent topic commissions
SELECT t.name, IFNULL(SUM(o.commission_amount), 0) AS commission
FROM topics AS t
LEFT JOIN orders AS o ON o.topic_id = t.id
WHERE t.topic_id IS NULL
GROUP BY t.name
) AS x
GROUP BY name
Here is a simpler look of the answer using self-join.
SELECT t1.name, SUM(o.commision_amount) AS commision
FROM topics t1
INNER JOIN topics t2 ON t1.id = t2.topic_id OR t1.id = t2.id
INNER JOIN orders o ON t2.id = o.topic_id
WHERE t1.topic_id IS NULL
GROUP BY t1.name;
See db<>fiddle
You can do a self-join to bring all parent topics, and children to the same level:
select TPnt.Name, sum(O.Commission_amount) as Commission_amount
from
Topics TPnt
inner join
Topics TChld
on TPnt.Id=coalesce(TChld.topic_id, TChld.id)
inner join
Orders O
on O.topic_id=TChld.id
group by TPnt.Name

GROUP BY within functions

I'm currently stuck with MySQL
SELECT
c.id_customer,
ROUND(SUM((o.commision_main + o.commision_delivery)/(
SELECT COUNT(o.id_order)
FROM orders AS o
INNER JOIN customers AS c
ON o.id_customer = c.id_customer
GROUP BY)), 2) AS profit
FROM orders AS o
INNER JOIN customers AS c
ON o.id_customer = c.id_customer
GROUP BY c.id_customer
I would love to make this SQL to use the COUNT for each id_customer that was GROUP BYed as well.
Picture of result And now it takes COUNT for every id_customer so it divides everything by 6 instead of 3 for id_customer 3, 2 for id_customer 1 and 1 for id_customer 66.
Help would be appreciated!
Your query seems needlessly complex, I am pretty sure you can get the result you are after with simply
SELECT o.id_customer,
ROUND(AVG(o.commision_main + o.commision_delivery) , 2) AS Profit
FROM Orders AS o
GROUP BY o.id_customer;
You should avoid the subquery for count() and use count() directly in main query
SELECT
c.id_customer,
ROUND(SUM((o.commision_main + o.commision_delivery)/COUNT(o.id_order)), 2) AS profit
FROM orders AS o
INNER JOIN customers AS c ON o.id_customer = c.id_customer
GROUP BY c.id_customer

mysql problem when doing 2 counts in the same query

First of all, apologies if this seems like a very dumb question, I have just started working with mySQL.
I have 2 tables:
1- Customer_courier_chat
2- Orders
Basically I want to do a query to count the amount of messages from a customer and the amount of messages from a courier. When I do an individual query to look for it, it works well but when I do both in the same query it returns different values.
The following query provides good results:
SELECT o.*, count(j.from_id) AS messages_courier
FROM test.orders o
INNER JOIN test.customer_courier_chat_messages j ON j.from_id = j.courier_id and o.order_id = j.order_id
Group BY o.order_id;
Results of the previous query messgaes from courier
The following one also provides good results:
SELECT o.*, count(k.from_id) AS messages_customer
FROM test.orders o
INNER JOIN test.customer_courier_chat_messages k ON k.from_id = k.customer_id and o.order_id = k.order_id
Group BY o.order_id;
Results of the previous query messages from customer
The main problem comes when I try to do both in the same query as the output is not correct.
SELECT o.*, count(j.courier_id) messages_courier, count(k.from_id) AS messages_customer
FROM test.orders o
INNER JOIN test.customer_courier_chat_messages j ON j.from_id = j.courier_id and o.order_id = j.order_id
INNER JOIN test.customer_courier_chat_messages k ON k.from_id = k.courier_id and o.order_id = k.order_id
Group BY o.order_id;
Results of previous query not working
Based on the results of the 2 invidiual queries, the previous one should provide:
order_id |city_code |messages_courier |messages_customer|
59528555 | ES | 2 | 5 |
11223344 | FR | 3 | 4 |
But, it actually provides:
order_id |city_code |messages_courier |messages_customer|
59528555 | ES | 4 | 4 |
11223344 | FR | 9 | 9 |
Am I missing something?
Thank you in advanced.
Kindly regards,
J
You can do it with conditional aggregation:
SELECT o.order_id, o.city_code,
SUM(m.from_id = m.courier_id) AS messages_courier,
SUM(m.from_id = m.customer_id) AS messages_customer
FROM test.orders o INNER JOIN test.customer_courier_chat_messages m
ON o.order_id = m.order_id
GROUP BY o.order_id, o.city_code;
You are first joining the table then using the count. You have to first pick get the count then use the join -
SELECT o.*, j.cnt messages_courier, k.cnt AS messages_customer
FROM test.orders o
INNER JOIN (SELECT order_id, COUNT(*) CNT
FROM test.customer_courier_chat_messages
WHERE from_id = courier_id
GROUP BY order_id) j ON o.order_id = j.order_id
INNER JOIN (SELECT order_id, COUNT(*) CNT
FROM test.customer_courier_chat_messages
WHERE from_id = customer_id
GROUP BY order_id) k ON o.order_id = k.order_id;

Mysql query count total from other table

Table jenis_usaha
ID JENIS_USAHA
1 Laundry
2 Restauran
Table waralaba
ID ID_JENIS_USAHA
1 1
2 2
Table perusahaan
ID NAME ID_WARALABA
1 A 1
2 B 2
3 C 1
4 D 1
Table outlet
ID ID_PERUSAHAAN
1 1
2 1
3 2
4 2
5 1
6 1
7 1
8 1
9 1
The result that I want is like this
ID JENIS_USAHA TOTAL_PERUSAHAAN TOTAL_OUTLET
1 Laundry 3 7
2 Restauran 1 2
I have this mysql query
SELECT ju.ID,
ju.JENIS_USAHA,
COUNT(p.ID) AS TOTAL_PEMBERI,
(SELECT count(o.ID)
FROM outlet o
WHERE p.ID = o.ID_PERUSAHAAN
AND w.ID = p.ID_WARALABA
AND ju.ID = w.ID_JENIS_USAHA
) AS TOTAL_OUTLET
FROM jenis_usaha ju
LEFT JOIN waralaba w ON w.ID_JENIS_USAHA = ju.ID
LEFT JOIN perusahaan p ON p.ID_WARALABA = w.ID
GROUP BY ju.ID
I've got no error BUT a wrong result for TOTAL_OUTLET. Could you please show me the right query for this? thanks
you did the wrong join that's why you got wrong output
below query should work as your way
select j.id ,j.name,TOTAL_PERUSAHAAN,outlet as TOTAL_OUTLET
from jenis_usaha j inner join
(select p.id,count(o.ID_PERUSAHAAN) as outlet from outlet o
inner join perusahaan p
on o.ID_PERUSAHAAN=p.id
group by p.id
) t1
on t1.id=j.id
inner join
(
select w.id, count(p.ID_WARALABA) as TOTAL_PERUSAHAAN
from waralaba w inner join perusahaan p
on w.id=p.ID_WARALABA
group by w.id
) t2
on t2.id=j.id
id name TOTAL_PERUSAHAAN TOTAL_OUTLET
1 Laundry 3 7
2 Restauran 1 2
here is fiddle link where you can find details
http://sqlfiddle.com/#!9/400c971/6
I was taking very long to understand your query, so I decided to do my own.
This one bring the results you wanted anyway. Please check if this works for your case. =)
Btw, st stands for subtotal
SELECT
st.id,
st.name,
count(ps_id) AS ps_amount,
sum(ol_amount) AS ol_amount
FROM
(SELECT
ju.id,
ju.name,
ps.id AS ps_id,
count(ol.id) as ol_amount
FROM
jenis_usaha ju
INNER JOIN
waralaba wl
ON wl.id_jenis_usaha = ju.id
LEFT JOIN
perusahaan ps
ON ps.id_waralaba = wl.id
LEFT JOIN
outlet AS ol
ON ol.id_perusahaan = ps.id
GROUP BY
ju.id,
ju.name,
ps.id) st
GROUP BY
st.id,
st.name

MySql Select query combine results

Hi im having 2 tables customers and customer_items.
There is now a customer_id in both tables in the 2nd table each customer can have multiple items so the table can be like this
id | item
----------------------------
1501 | pillow
1501 | blanket
1501 | others
1502 | pillow
1502 | blanket
1502 | others
now how can i select with a mysql query the customers that have both pillow and blanket
This is my last approach
select custlist.id FROM customers custlist LEFT JOIN customer_items custitems ON custitems.id=custlist.id WHERE (custitems.items='pillow' AND custitems.items='blanket') UNION ALL
This is a Relational Division problem.
SELECT a.customer_ID
FROM customers a
INNER JOIN customer_items b
ON a.customer_ID = b.customer_ID
WHERE b.item IN ('pillow', 'blanket')
GROUP BY a.customer_ID
HAVING COUNT(*) = 2
SQL of Relational Division
If item is not unique for every customer_ID, a DISTINCT keyword is need to count only unique records.
SELECT a.customer_ID
FROM customers a
INNER JOIN customer_items b
ON a.customer_ID = b.customer_ID
WHERE b.item IN ('pillow', 'blanket')
GROUP BY a.customer_ID
HAVING COUNT(DISTINCT b.item) = 2
Slight variation of the above solution by JW:-
SELECT a.customer_ID
FROM customers a
INNER JOIN (SELECT customer_ID, item FROM customer_items WHERE item = 'pillow' GROUP BY customer_ID) PillowCheck
ON a.customer_ID = PillowCheck.customer_ID
INNER JOIN (SELECT customer_ID, item FROM customer_items WHERE item = 'blanket' GROUP BY customer_ID) BlanketCheck
ON a.customer_ID = PillowCheck.customer_ID
Try this query
SELECT
a.id
FROM
customer_items a
INNER JOIN
customer_items b
ON
a.id= b.id and
a.item = 'PILLOW' AND
b.item='blanket'
if you want customer name then just join customer table. If customer have multiple pillow or blanket then add distinct
SELECT
distinct customer_ID ,item
FROM
customer_items
WHERE item in ('PILLOW', 'blanket')
GROUP BY customer_ID
HAVING COUNT(item) = 2