Find all individual item purchase by all user in mysql [duplicate] - mysql

This question already has an answer here:
MySQL pivot row into dynamic number of columns
(1 answer)
Closed 4 years ago.
I have three tables e.g client, product and purchase.
Purchase:
id productId clientId amount
1 1 2 2500
2 2 3 3500
3 3 4 4500
4 6 1 5500
5 1 2 1500
6 3 3 2000
7 3 2 1000
Client:
id name
1 A
2 B
3 C
4 B
Product:
id product
1 Apple
2 Banana
3 Mango
6 Sweet
I am able to query this
SELECT client.id, client.client_name, product.product, purchase.amount from client INNER JOIN purchase ON client.id=purchase.clientId INNER JOIN product ON product.id=purchase.productId GROUP BY client.id
My output is:
id client_name product amount
1 A Sweet 5500
2 B Apple 2500
3 c Mango 3500
4 D Banana 4500
But I want output like where is the amount of each client purchased
Desired Output:
id client_name Apple Banana Mango Sweet
1 A x x x x
2 B X x x x
3 c X x x x
4 D x x x x
How can I do that with query. thanks

If you have a limited products then i would use conditional aggregation :
SELECT c.id, c.client_name,
SUM(CASE WHEN pd.id = 1 THEN p.Amount ELSE 0 END) AS Apple,
SUM(CASE WHEN pd.id = 2 THEN p.Amount ELSE 0 END) AS Banana,
SUM(CASE WHEN pd.id = 3 THEN p.Amount ELSE 0 END) AS Mango,
SUM(CASE WHEN pd.id = 6 THEN p.Amount ELSE 0 END) AS Sweet
FROM client c INNER JOIN
purchase p
ON c.id = p.clientId INNER JOIN
product pd
ON pd.id = p.productId
GROUP BY c.id, c.client_name;

The easiest way if your Purchase table is static
select
c.id,
c.name,
(select SUM(p.amount) from Purchase p where p.productId = 1 and p.clientId = c.id) as Apple,
(select SUM(p.amount) from Purchase p where p.productId = 2 and p.clientId = c.id) as Banana,
(select SUM(p.amount) from Purchase p where p.productId = 3 and p.clientId = c.id) as Mango,
(select SUM(p.amount) from Purchase p where p.productId = 6 and p.clientId = c.id) as Sweet
from Client c

Related

selecting items in MySQL

i want to select booktitle with status paid
but if there no booktitle with status paid display other booktitle with other status
ITEMS
ID bookname code
1 cats 222
2 dogs 555
3 cows 777
4 goat 888
5 rubbit 999
PRODUCTS
ID booktitle status
1 222 paid
2 555 paid
3 777 notpyed
4 888 waitpyed
5 999 notmoney
Query
SELECT
snd.code, m.booktitle FROM
products as m
JOIN items as snd ON snd.code = m.booktitle WHERE CASE WHEN (m.status = 'paid') > 0 THEN m.status = 'paid' ELSE m.status = 'notpyed' OR m.status = 'waitpyed'
OR m.status = 'notmoney' END
You use a subquery to get the sum of books paid
The else part could be m.status <> 'paid' , but i don't know how many sti you have
SELECT
snd.code, m.booktitle FROM
PRODUCTS as m
JOIN ITEMS as snd ON snd.code = m.booktitle
WHERE CASE WHEN (SELECT SUM(status = 'paid') FROM PRODUCTS) > 0 THEN m.status = 'paid'
ELSE m.status = 'notpyed' OR m.status = 'waitpyed'
OR m.status = 'notmoney' END
code | booktitle
---: | --------:
222 | 222
555 | 555
db<>fiddle here

mysql query not working as expected complex

I have 3 tables in which all 3 tables are joined to get the result.
Below is the table,
//tbl_order
order_id order_no_first order_no order_no_last order_date
---------------------------------------------------------------------
1 C 1000 a 2017-05-16
2 C 1001 a 2017-05-16
3 C 1001 b 2017-05-16
4 A 1002 a 2017-05-16
5 A 1002 b 2017-05-16
//tbl_assign
assign_id order_id order_no_first central_status central_assign_unit
----------------------------------------------------------------------------
1 1 C 1 1
2 2 C 1 1
3 3 C 1 1
4 4 A 1 1
//tbl_unit_status
status_id assign_id status_status
---------------------------------------
1 1 Cutter
2 1 Stitch
3 1 Delivery
4 2 Cutter
5 2 Stitch
6 3 Cutter
7 4 Cutter
I want the result as below,
//Required output
order_id assign_id order_no_first order_no order_no_last status_status
---------------------------------------------------------------------------
2 2 C 1001 a Stitch
3 3 C 1001 b Cutter
4 4 A 1002 a Cutter
5 A 1002 b
from the table tbl_unit_status the status below status_status field, if it is Despatch then do not display that result.
I have tried to get the above result. But no success below is my code.
`SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id AND o.order_no_first = a.order_no_first
LEFT JOIN (
SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u GROUP BY u.assign_id) uu
ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 AND a.central_assign_unit = 1
OR (u2.status_status != "Delivery" AND u2.status_status != "Despatch")
GROUP BY o.order_id
From the above code, the result is
//wrong output
order_id assign_id order_no_first order_no order_no_last status_status
---------------------------------------------------------------------------
1 1 C 1000 a Delivery
2 2 C 1001 a Stitch
3 3 C 1001 b Cutter
4 4 A 1002 a Cutter
5 A 1002 b
Is there any way to get the Required output as soon in the first output. I have tried and am stuck in here.
Thank you.
Use parenthesis correctly arround AND OR clauses and I recommend using NOT LIKE instead of != when dealing with strings.
SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id AND o.order_no_first = a.order_no_first
LEFT JOIN (
SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u GROUP BY u.assign_id) uu
ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 AND (a.central_assign_unit = 1 OR u2.status_status NOT LIKE 'Delivery' AND u2.status_status NOT LIKE 'Despatch')
GROUP BY o.order_id
Obs: I can't comment due to my reputation, I'm sorry
You should be using AND instead of OR in your where clause. You don't need the parentheses either.
SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id
AND o.order_no_first = a.order_no_first
LEFT JOIN
(SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u
GROUP BY u.assign_id
) uu ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2
on u2.status_id = uu.maxid
WHERE a.central_status = 1
AND a.central_assign_unit = 1
AND (
u2.status_status IS NULL
OR
u2.status_status NOT IN ("Delivery", "Despatch")
)
GROUP BY o.order_id

How to select counts from different tables with foreign keys?

city
----------------------
id city_name
1 Pune
2 Mumbai
3 Banglore
Branches
----------------------
id branch_name city_id
1 Magarpatta 1
2 Wagholi 1
3 Kurla 2
4 CST 2
5 Thane 2
6 Anekal 3
Employees
----------------------
id employee_name city_id
1 Arun 1
2 Varun 1
3 Mahesh 2
4 Umesh 2
5 Prakash 1
6 Kedar 3
Expected result
-----------------------------
id(city) city_name No_of_Branch no_of_employee
1 Pune 2 3
2 Mumbai 3 2
3 Banglore 1 1
Can I get above result in single Query?
Can I Use Crosstab in this scenario? How?
SELECT c.*, count(DISTINCT b.id) AS No_of_Branch, count(DISTINCT e.id) AS no_of_employee
FROM city c
LEFT JOIN branches b ON (b.city_id=c.id)
LEFT JOIN employees e ON (e.city_id=c.id)
GROUP BY c.id
Or
SELECT c.*,
(SELECT count(b.id) FROM branches b WHERE b.city_id=c.id) AS No_of_Branch,
(SELECT count(e.id) FROM employees e WHERE e.city_id=c.id) AS no_of_employee
FROM city c
Try this:
SELECT c.id, c.city_name,
COUNT(b.id) AS No_of_Branch,
no_of_employee
FROM city c
LEFT JOIN branches b ON b.city_id = c.id
LEFT JOIN (
SELECT city_id, COUNT(e.id) AS no_of_employee
FROM employees AS e
GROUP BY e.city_id
) AS e_grp ON e_grp.city_id = c.id
GROUP BY c.id, c.city_name
The trick here is to use a derived table containing the count of employees per city_id. I you just join all tables together you will end up with duplicate counts of employees.
Demo here

mysql complicated inner join on many to many

I have 7 tables db_category, db_city, db_locality, db_shop, db_shop_locality, db_shop_recommended, db_shop_views.
db_category
category_id category_name publish
1 Apparel 1
db_city
city_id city_name publish
1 bangalore 1
db_locality
locality_id locality_name publish
1 kalyan nagar 1
2 Madiwala 1
db_shop
shop_id category_id city_id locality_id shop_name publish
1 1 1 1 name 1
2 1 1 2 name1 1
3 1 1 1 name2 1
4 1 1 1 name3 1
db_shop_recommended
recommended_id category_id shop_id priority publish
1 1 1 1 1
2 1 2 2 1
db_shop_views
views_id shop_id ip_addr publish
1 1 127.0.0.1 1
2 2 ::1 1
3 4 127.0.0.1 1
4 4 ::1 1
5 3 ::1 1
I want to join all the above tables. And the conditions for the join are,
display all the rows from db_shop when publish=1 and join db_category, db_city and db_locality with db_shop
in db_shop_recommended who's priority=1 comes first and so on.
and shop_id not in db_shop_recommended, count shop_id not in db_shop_recommended from db_shop_views who's shop_id got more views.
My result should looks like below,
shop_id category_name city_name locality_name shop_name
1 Apparel bangalore kalyan nagar name (result based on `db_shop_recommended` who's priority is more)
2 Apparel bangalore Madiwala name1 (result based on `db_shop_recommended` who's priority is more)
4 Apparel bangalore kalyan nagar name4 (result based on `db_shop_views` who's view count is more)
3 Apparel bangalore kalyan nagar name3 (result based on `db_shop_views`)
I have no idea how to join and count the views. Is it possible to join in above method.
After lots of searching. Finally i got the answer.
SELECT DISTINCT s.shop_id, c.city_name, l.locality_name, ca.category_name, s.shop_name, s.shop_logo, s.cart_url, s.shop_about FROM db_shop s INNER JOIN db_city c ON c.city_id = s.city_id INNER JOIN db_category ca ON ca.category_id = s.category_id INNER JOIN db_locality l ON l.locality_id = s.locality_id LEFT JOIN (SELECT * FROM db_shop_recommended r ORDER BY r.priority ASC) r1 ON s.shop_id = r1.shop_id LEFT JOIN (select distinct g.shop_id, g.cnt from (select distinct shop_id, count(shop_id) cnt from db_shop_views group by shop_id) g inner join (select max(s.cnt) max_cnt from(select distinct shop_id, count(shop_id) cnt from db_shop_views group by shop_id) s) m on m.max_cnt = g.cnt) v ON s.shop_id = v.shop_id WHERE s.publish = 1

MySQL returns incorrect data with use of join

I have join with a multiple tables. You can find the tables and MySQL query in this demo.
These are the tables:
users
id name
1 abc
2 xyz
3 pqr
friend
user_id friend_id
1 2
1 3
2 3
collection
id user_id friend_id amount
1 1 2 100
2 2 1 -100
3 2 3 200
4 3 2 -200
5 1 3 300
6 3 1 -300
bill
id use_id(bill_creator)
1 1
2 2
3 2
bill_person
id bill_id user_id
1 1 1
2 1 2
3 1 3
4 2 2
5 2 3
6 3 2
6 3 1
So far I have made this query:
SELECT mf.id
, mf.name
, c.amount AS amount,count(bp.user_id) AS no_common_bills
FROM (
SELECT fr.user_id AS user_id
, fr.friend_id AS friend_id
FROM friend fr
JOIN users fru
ON fru.id = fr.user_id
WHERE fru.id IN (1)
UNION
SELECT fl.friend_id AS user_id
, fl.user_id AS friend_id
FROM friend fl
JOIN users flf
ON flf.id = fl.friend_id
WHERE flf.id IN (1)
) f
JOIN users mf
ON mf.id = f.friend_id
LEFT
JOIN collection c
ON c.friend_id = mf.id
AND c.user_id = f.user_id
LEFT JOIN bill_person bp
ON bp.user_id=f.user_id AND c.friend_id = mf.id
GROUP BY mf.id
ORDER BY mf.id
and my output of this query is
id NAME AMOUNT NO_COMMON_BILLS
2 XYZ 100 2
3 PQR 300 2
but I want this result:
id NAME AMOUNT NO_COMMON_BILLS
2 XYZ 100 2
3 PQR 300 1
I am getting wrong output at NO_COMMON_BILLS. Other than that, all values are correct.
Third time's a charm...
http://sqlfiddle.com/#!2/338dd/12
SELECT u.name friend
, COUNT(bp2.user_id) no_common_bills
FROM users u
LEFT
JOIN
( SELECT user_id me, friend_id them FROM friend WHERE user_id = 1
UNION
SELECT friend_id,user_id FROM friend WHERE friend_id = 1
) x
ON x.them = u.id
LEFT
JOIN bill_person bp1
ON bp1.user_id = x.them
LEFT
JOIN bill_person bp2
ON bp2.bill_id = bp1.bill_id
AND bp2.user_id = x.me
WHERE u.id <> 1
GROUP
BY friend;
FRIEND NO_COMMON_BILLS
jkl 0
mno 0
pqr 1
xyz 2