How to show usernames using GROUP_CONCAT? - mysql

I am trying to figure out how to show usernames instead of userid's in a mysql query that users GROUP_CONCAT. The following query works but shows user id's. How can I show usernames instead?
The query
SELECT p.user_name, p.user_id, up.file, GROUP_CONCAT(c.userid)
FROM tbl_uploads up
LEFT JOIN tbl_users p ON up.user_id = p.user_id
LEFT JOIN tbl_collab c ON up.file = c.file
GROUP BY up.file
Results
user_name | user_id | file | GROUP_CONCAT(c.userid)
Peter 5 pic_1.jpg 2,5
Mary 6 pic_2.jpg 6
julian 2 pic_3.jpg (null)

Join the users table one more time, and get the usernames from there:
SELECT p.user_name, p.user_id, up.file, GROUP_CONCAT(cp.user_name)
FROM tbl_uploads up
LEFT JOIN tbl_users p ON up.user_id = p.user_id
LEFT JOIN tbl_collab c ON up.file = c.file
LEFT JOIN tbl_users cp ON cp.user_id = c.userid
GROUP BY up.file

Presumably, tbl_users has user names. If so, use that for the GROUP_CONCAT():
SELECT up.file, GROUP_CONCAT(p.username)
FROM tbl_uploads up LEFT JOIN
tbl_users p
ON up.user_id = p.user_id LEFT JOIN
tbl_collab c
ON up.file = c.file
GROUP BY up.file;
Note I removed p.username from the SELECT. In general, in an aggregation query, all columns/expressions should either be in the GROUP BY or arguments to aggregation functions.

Related

Why is my join query not giving the expected result for three tables

I have a problem with 3 tables join I'm able to get the desired result for
2 tables which have ids: 138 , 140 , 141
here is my query(Getting Desired Result)
SELECT distinct u.*
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
Here is a demo:http://sqlfiddle.com/#!9/360836/1
Now I want to join the third table to get CONCATENATED skills String like (html,css,mysql,php)
Here is the query (3 results expected, getting only 1)
SELECT distinct u.*,GROUP_CONCAT(uskill.skills) skills
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
left join user_skills uskill on u.user_id = uskill.user_id
Here is a demo:http://sqlfiddle.com/#!9/360836/3
Please help me get 3 results with skills
Thanks in advance!
Below query can solve your problem
SELECT u.*,GROUP_CONCAT(distinct uskill.skills) skills
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
left join user_skills uskill on u.user_id = uskill.user_id
group by u.user_id
you need to use group by to get different user details and add distinct keyword inside GROUP_CONTACT to get distinct skills.
You need to Distinct with Group_Concat like this
SELECT distinct u.*,GROUP_CONCAT(DISTINCT uskill.skills) skills
from jobs_applied_by_jobseeker_for_employer jbs
Left join user_details u on u.user_id = jbs.employee_id
left join user_skills uskill on u.user_id = uskill.USER_ID

Left join on 3 tables?

I have to use LEFT JOIN on 3 tables: UNITS, ROOMS_CHECK_IN and COMMENTS. Basically I want to show UNITS and for each unit count of rooms check in and count of comment. But I am getting same 4 digit number when I am running for rooms check in and comment count. If I separate the 2 queries with single left join, it works fine.
Below is the query:
SELECT u.ID,
u.unit_name,
count(c.checkin_status) as total_chekin ,
count(com.ID) as total_comment ,
h.hospital_name
FROM HOSPITALS h, UNITS u
LEFT OUTER JOIN ROOMS_CHECK_IN c ON c.unit_id = u.ID AND c.room_status=0
LEFT OUTER JOIN COMMENTS com ON com.unit_id = u.ID
WHERE h.ID = u.hospital_id AND u.hospital_id=3
GROUP BY u.ID;
Kindly help.
Never use commas in the FROM clause. Always use explicit proper JOIN context.
Then, you probably want count(distinct) (or to aggregate before joins):
SELECT u.ID, u.unit_name,
count(distinct c.checkin_status) as total_chekin,
count(distinct com.ID) as total_comment,
h.hospital_name
FROM HOSPITALS h JOIN
UNITS u
ON h.ID = u.hospital_id LEFT OUTER JOIN
ROOMS_CHECK_IN c
ON c.unit_id = u.ID AND c.room_status = 0 LEFT OUTER JOIN
COMMENTS com
ON com.unit_id = u.ID
WHERE u.hospital_id = 3
GROUP BY u.ID, u.unit_name, h.hospital_name;

Get results when where value is 'grade' or where it doesn't exist

I have a wordpress site that is used to store student grades on various lessons (from the quizzes on the site). I am trying to create a query that will pull out all of the lessons for all students in a certain group (using buddypress groups) and the students grades in each lesson.
I have created this query:
SELECT u.display_name, p.post_title, cm.meta_value
FROM wp_users u
JOIN wp_bp_groups_members gm
ON u.ID = gm.user_id
JOIN wp_comments c
ON u.ID = c.user_id
JOIN wp_commentmeta cm
ON c.comment_ID = cm.comment_id
JOIN (SELECT * FROM wp_posts WHERE post_type LIKE 'lesson') p
ON c.comment_post_id = p.ID
WHERE gm.group_id = 4 AND cm.meta_key LIKE 'grade'
This currently returns all the grades for all students in a group in the lessons they have attempted the test. However it does not return any lessons they have not attempted the test in, which I need still.
Just to be clear: lessons are posts, grades are meta_values in a record with a meta_key of 'grades'. These are stored as comments, and comment_meta.
I hope this is all clear and you can help. Thanks.
After Ollie Jones help I made this:
SELECT u.display_name, p.post_title, IFNULL(cm.meta_value,'--nothing--') grade
FROM wp_users u
JOIN wp_comments c
LEFT JOIN wp_commentmeta cm
ON c.comment_ID = cm.comment_id AND cm.meta_key = 'grade'
JOIN wp_bp_groups_members gm
ON u.ID = gm.user_id
JOIN wp_posts p
ON c.comment_post_id = p.ID
WHERE gm.group_id = 4 AND p.post_type LIKE 'lesson'
Which almost works but returns all student grades, not just the ones in the group (though it only gives the one name of the student in the group).
This is the familiar key/value store problem, that comes up with commentmeta, postsmeta, and usermeta. When you JOIN two tables and the left one might not have a corresponding row, you need to use LEFT JOIN. When the left one is a key/value table, you need to adjust the ON condition accordingly. Finally, when you LEFT JOIN two tables and there's no matching row in it it, you get back NULLs for those columns, so you must allow for that.
So this kind of SQL pattern will do the trick for you
SELECT whatever, IFNULL(cm.meta_value,'--nothing--') grade
FROM whatever
LEFT JOIN wp_comments c ON whatever.id = c.user_id
LEFT JOIN wp_commentmeta cm ON c.comment_id = cm.comment_id
AND cm.meta_key = 'grade'
JOIN whatever
Is there a user_id in your comments table? I dont see where you joined which user posted which comment. So when you join the group_members to the users table, you are specifying which users to show, but since you are not joining on user id when you join to your comments table, it will show all the comments for all the users. Im not sure if this will work for your table, but try:
SELECT u.display_name, p.post_title, IFNULL(cm.meta_value,'--nothing--') grade
FROM wp_users u
LEFT JOIN wp_comments c
JOIN wp_commentmeta cm
ON c.comment_ID = cm.comment_id AND cm.meta_key = 'grade'
JOIN wp_bp_groups_members gm
ON c.user_ID = gm.user_id
ON u.user_id = c.user_id
JOIN wp_posts p
ON c.comment_post_id = p.ID
WHERE gm.group_id = 4 AND p.post_type LIKE 'lesson'
Hope this helps!

mysql sum using left join on three tables

We have following tables...
users
id, username password email
user_clubs
id, user_id, club_name
sales
id, club_id, amount, admin_fees, dnt
We are trying to get total sum of admin_fees as outstanding for user_id(for example 5), and we tried following...
SELECT u.id, count(c.id), SUM(s.admin_fees) as total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
WHERE u.id = 5
GROUP BY u.id;
Which is only returning results for first row, which is incorrect, Please help to resolve.
here is sql fiddle to test.
thanks
Try this one for user_id = 5 there are two club ids and with amount 2,5 so total should be 7
SELECT u.id, COUNT(c.id), SUM(s.admin_fees) AS total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
WHERE u.id = 5
GROUP BY s.club_id;
for all users you can do this
SELECT u.id, COUNT(c.id), SUM(s.admin_fees) AS total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
GROUP BY u.`id`;
Fiddle

Selecting All Rows in SQL, With Specific Criteria

I have a fairly complicated SQL statement I am working on. Here is where I am at:
SELECT c.category
FROM master_cat as c
LEFT JOIN
(
SELECT cat_id, user_id COUNT(cat_id) favoriteCat
FROM ratings
GROUP BY user_id
) a ON a.cat_id= c.cat_id
LEFT JOIN users AS u
ON u.user_id AND a.user_id
WHERE u.username = '{$user}' LIMIT 1
This statement is incomplete. I am missing a middle table here. cat_id is not actually in ratings. But items_id is from a table called items and cat_id is also in that table as well.
So what I am trying to do is this:
SELECT rating FROM ??? GROUP BY cat_id where u.user=$user
The only thing I can think of doing maybe is another LEFT join with items inside favoriteCat but I am not sure if that is allowed.
I was overthinking this, here is my final solution:
SELECT c.category, count(r.rating) AS totalCount
FROM ratings as r
LEFT JOIN items AS i
ON i.items_id = r.item_id
LEFT JOIN users AS u
ON u.user_id = r.user_id
LEFT JOIN master_cat AS c
ON c.cat_id = i.cat_id
WHERE r.user_id = '{$user_id}'
GROUP BY c.category
ORDER BY totalCount DESC