Reputation: 705
So I have the following table, users
:
+-----------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------+
| uid | int(10) unsigned | NO | PRI | 0 | |
| name | varchar(60) | NO | UNI | | |
---------------------------------------------------------------
And the table, roles
:
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| rid | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | UNI | | |
+-------+------------------+------+-----+---------+----------------+
I have a third table, users_roles
, which in a one-to-many relationship maps users
to one or more roles
:
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| uid | int(10) unsigned | NO | PRI | 0 | |
| rid | int(10) unsigned | NO | PRI | 0 | |
+-------+------------------+------+-----+---------+-------+
Finally, I have a fourth table, memberships
, that maps one-to-one with users
:
+-------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------+------+-----+---------+-------+
| membership_no | varchar(32) | NO | PRI | NULL | |
| uid | int(11) | YES | | NULL | |
--------------------------------------------------------------------
Currently I have a nice and simple query that provides a list of users with their membership number:
SELECT u.uid, u.name, m.membership_no FROM users AS u
LEFT JOIN memberships AS m ON u.uid = m.uid;
But now I would like to add an additional column to my query that looks up all the users_roles
entries once per user, and then concatenates each roles.name
in one column, so I can see all the roles for that user. An example output might be:
uid name membership no roles
--- ---- ----- ------
1 foo 123432 admin, normal user, student
2 bar baz 235235 admin
3 bak 2352352 normal user, student
So my task is how I would integrate this additional query on the users_roles
table, link user_roles.rid
to roles.rid
and concatenate the data in a column. Any pointers?
Upvotes: 0
Views: 55
Reputation: 227200
You're looking for GROUP_CONCAT
. First JOIN the other tables, so you can get the role names, then GROUP them together by user id.
SELECT u.uid, u.name, m.membership_no, GROUP_CONCAT(r.name ORDER BY r.rid) AS roles
FROM users AS u
LEFT JOIN memberships AS m ON u.uid = m.uid
JOIN users_roles AS ur ON u.uid = ur.uid
JOIN roles AS r ON ur.rid = r.rid
GROUP BY u.uid
DEMO: http://sqlfiddle.com/#!2/ffa31/1
Upvotes: 4
Reputation: 3135
Use MySQL GROUP_CONCAT function.
SELECT
u.uid,
u.name,
m.membership_no,
(SELECT GROUP_CONCAT(name) FROM users_roles ur INNER JOIN roles r ON r.rid = ur.rid WHERE ur.uid = u.uid) as roles
FROM users AS u
LEFT JOIN memberships AS m ON u.uid = m.uid;
Upvotes: 3