I have a database with two tables users and orders
users: user_id(primary), fname, lname, email, password, gender
orders: order_no(primary), user_id(foriegn), beans, type, extras, city
The orders table have only users who submitted orders.
I need to know how to select all users with the count of their orders if they have orders or don't.
Additional Info posted as an answer....
users table:
user_id fname lname email password gender
1 a aa aaa 123 m
2 b bb bbb 34 f
orders table:
order_no user_id bean type extras city
1 2 s d rr ggg
2 2 s d rr ggg
how to select all users table columns plus orders count for a and b so the new table will be:
user_id fname lname email password gender orders_count
1 a aa aaa 123 m 0
2 b bb bbb 34 f 2
select U.user_id,
COUNT(O.user_id)
from users U
left join orders O on U.user_id=O.user_id
group by U.user_id
Based on the updated information, use:
SELECT u.*,
COALESCE(x.orders_count, 0) AS orders_count
FROM USERS u
LEFT JOIN (SELECT o.user_id,
COUNT(*) AS orders_count
FROM ORDERS o
GROUP BY o.user_id) x ON x.user_id = u.user_id
ORDER BY u.user_id
Your update is basically requesting what pcofre's answer already gives you. You just need to add the additional required columns to your select list and provide a column alias for the aggregate.
SELECT U.user_id,
U.fname,
U.lname,
U.email,
U.password,
U.gender,
COUNT(O.user_id) AS orders_count
FROM users U
LEFT JOIN orders O
ON U.user_id = O.user_id
GROUP BY U.user_id /*<-- Don't need to add other users
columns to GROUP BY in MySQL*/
Related
I have an users table and amount table.
The users table has following columns.
name id
A 1
B 2
C 3
D 4
The amount table has following columns.
userId amount id
1 10 1
1 20 2
1 10 3
2 12 4
I need a sql which sums all the users amount from the amount table
Final output would be
name id totalAmount
A 1 30
B 2 12
C 3 0
D 4 0
I have tried using but does not work. Kindly help
let searchQuery = `SELECT u.id, u.name, (SELECT IFNULL(SUM(amount), 0) from amount WHERE amount.userId = u.id) as totalAmount, FROM users u LEFT JOIN amount amt on u.id = amt.userId WHERE`;
Correct syntax for correlated subquery version
SELECT u.id, u.name, (SELECT coalesce(SUM(a.amount), 0)
FROM amount a
WHERE a.userId = u.id) as totalAmount
FROM users u
You can do it using standard sql aggregation
select
u.name,
u.id,
sum(a.amount) as totalAmount
from users u
left join amount a
on a.userId = u.id
group by u.name, u.id
The left join is just to include those users whitout amounts, which will have a 0 as totalAmount
I have a user_groups table, a users table and an orders table.
The relationship between them is this: users.group_id, orders.user_id.
I'm trying to get the amount of users that belong to each group, and the amount of orders that belong to each group through its users.
My code:
select user_groups.*, count(users.id) as user_count, count(orders.id) as order_count
from user_groups
left join users on user_groups.id=users.group_id
left join orders on users.id=orders.user_id
group by user_groups.id
Expected output:
id | user_count | order_count
1 | 5 | 67
2 | 1 | 1
Actual output:
The amount of orders should be 5, not 71:
Use count(distinct):
select ug.*, count(distinct u.id) as user_count, count(distinct o.id) as order_count
from user_groups ug left join
users u
on ug.id = u.group_id left join
orders o
on u.id = o.user_id
group by ug.id;
count(id) counts the number of non-NULL values. You apparently want to count the number of different values, which is what distinct does.
I have 3 tables:
tbl_user stores all user details (user_id,name,address)
user_id name address
1 a (shop) home
2 b (shop) bakerstreet
3 c (staff) wallstreet
4 d (staff) georgia
5 e (staff) sydney
tbl_user_group stores user type (user_id,user_type : 1=shop_owner,2=staff)
user_id user_type
1 1
2 1
3 2
4 2
5 2
tbl_user_association holds the shop_owner and staff relation (shop_owner_id, staff_id)
shop_owner_id staff_id
1 3
1 4
1 5
2 3
2 4
desired result
i want to display the list of staffs and the respective shops that they are associated with as follows:
user_id staff_name shop_owner
3 c a,b
4 d a,b
5 e a
I tried using the group_concat as mentioned here. The query is as follows:
SELECT
u.id AS user_id,
u.name AS staff_name,
(SELECT GROUP_CONCAT(u.name separator ',') FROM tbl_user u WHERE u.id = ua.shop_owner_id) AS
shop_owner
FROM tbl_user u
JOIN tbl_user_group ug ON u.id = ug.user_id
LEFT JOIN tbl_user_association ua ON u.id = ua.staff_id
WHERE ug.user_type = 2
GROUP BY u.id
But it returns single row of staffs as below. where have i gone wrong?
user_id staff_name shop_owner
3 c a
4 d a
5 e a
This is how I'd do it:
SELECT
u.user_id,
u.name,
GROUP_CONCAT( so.name )
FROM
tbl_user_group ug
INNER JOIN tbl_user u
ON ( ug.user_id = u.user_id )
INNER JOIN tbl_user_association ua
ON ( ua.staff_id = u.user_id )
INNER JOIN tbl_user so -- here join again the user table to get shop owners names
ON ( ua.shop_owner_id = so.user_id )
WHERE
ug.user_type = 2
GROUP BY
u.user_id;
I have the following database:
user_id and contact_id from Contacts table are PK and FK to the user_id field in the Users table. How can i select all contacts (or friends) of a specific user including the number of contacts of all contacts of this user. I tried different SELECT queries but either the number of contacts is incorrect or the contact_status is printed wrong. I use COUNT() as a function to print the number of contacts. I use this query but the contact_status is printed wrong:
SELECT COUNT(Contacts.contact_id), Users.user_id, Users.user_name, Users.name, Users.user_picture, Users.mood_message, Users.phone_number, Users.email, Users.country, Users.city, Users.website, Users.birth_date, Users.gender, Users.language, Users.about_me, Users.online_status, Users.privacy, Contacts.contact_status
FROM Contacts JOIN Users ON Contacts.contact_id = Users.user_id
WHERE Users.user_name IN (
SELECT Users.user_name
FROM Users
WHERE Users.user_id IN (
SELECT Contacts.contact_id
FROM Contacts
WHERE Contacts.user_id = 12
)
)
GROUP BY Users.user_name;
Users Table:
user_id, user_name, ...
12 John ...
13 Matt ...
14 Jack ...
Contacts Table:
user_id, contact_status, contact_id
12 1 13
13 1 12
12 2 14
If i want to print all Contacts of John the result should consist:
COUNT(Contacts.contacts_id), Users.user_name, Users. ... , Contacts.contact_status
1 Matt ... 1
0 Jack ... 2
The above query prints 1, 1 as a contact_status instead of 1, 2.
Can you help me with this query? Thanks in advance.
If I understood what's your goal, this should work:
SELECT c.contact_status, cc.contactCount, u.*
FROM Contacts c JOIN Users u ON (c.contact_id = u.user_id)
JOIN (
SELECT user_id, COUNT(1) contactCount FROM Contacts
GROUP BY user_id
) cc ON (c.user_id = cc.user_id)
WHERE c.user_id = 12
I hope I understand ur requirements, but its much simpler to use a subquery, like so:
SELECT
u.* -- Whatever fields you need
,(
select count(*) from Contacts c
where c.contactid = co.userid -- refers to outer record
) as contact_count
FROM
Users u Inner Join Contacts co
on co.UserId = u.UserId
WHERE
U.UserId = 12
I have 3 tables in my mysql DB to query.
Users_rates (fields: id,userid,raterid,rate,eventid) containing all of the rates(rate) that have been assigned to users(userid), participating to specific events(eventid), by other users(raterid)
Events_participants (fields:id,userid,eventid) containing all of the users(userid) participating to each event(eventid)
Users (fields:id,name,lastname)containing all the user relative data
I need to query those three tables to retrieve an event-specific rank for the users' rates.
Ex. John,Erik and Mark participated to 'eventid=31'.
John received 1 rate from Mark, and 2 from Erik.
Mark received 1 rate from Erik.
Nobody has rated Erik though.
I need to retrieve for each user name,lastname and the sum of the rates received for eventid=31
I tried with this:
SELECT events_participants.userid,users.name,users.lastname,
(SELECT SUM(rate)FROM users_rates WHERE users_rates.eventid=31 AND users_rates.userid=events_participants.userid)AS rate
FROM(( events_participants INNER JOIN users ON events_participants.userid=users.id)
LEFT OUTER JOIN users_rates ON events_participants.userid=users_rates.userid )
WHERE events_participants.eventid=31
But I receive:
userid | name | lastname | rate
1 | luca | silvestro | 1
3 | claudio | buricchi | 6
3 | claudio | buricchi | 6
What's the right query?
Thanks
Luca
Try this:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users LEFT JOIN (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp USING (userid)
It might give an error, this might work instead:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users, (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp WHERE users.userid = temp.userid
I don't know if I got the problem right, but maybe something like:
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN users_rates AS ur ON ur.userid = u.id
WHERE ur.eventid = 31
GROUP BY u.id
edit: If you want to receive a list with all users regardless of whether they have any rates at all, you could also join the users_participants table and replace the INNER JOIN of users_rates by a LEFT JOIN. The WHERE clause has to reference events_participants then (not users_rates anymore as it could be NULL):
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN events_participants AS ep ON ep.userid = u.id
LEFT JOIN users_rates AS ur ON ur.userid = u.id AND ur.eventid = ep.eventid
WHERE ep.eventid = 31
GROUP BY u.id