I have a mySQL database in which I'm trying to output a list of users and their assigned, administrative roles. My tables look something like:
Users:
-------
- id
- fname
- lname
Role_Names
-----------
- rn_id
- role_name
Roles
---------
- role_id
- user_id
here's some data:
Users:
-------
1 'Chris' 'Christy'
2 'Brian' 'Bobson'
3 'Jen' 'Sanders'
Role_Names
--------------
1 'admin'
2 'exec'
3 'employee'
Roles
-----------
1 1
1 2
1 3
2 3
3 3
3 2
and for my query, I'm using:
SELECT Users.fname, Role_Names.role_name from Users INNER JOIN
Roles on Users.id = Roles.user_id
INNER JOIN Role_Names
ON Roles.rn_id = Roles.role_id;
It only seems to be outputting roles for the 1st user_id
in the Roles
table. And it's outputting more than 1 of the same record. For example, my output looks like:
first_name role_name
--------------------------------------
Chris exec
Chris exec
Chris exec
Chris employee
Chris employee
Chris employee
Chris admin
Chris admin
Chris admin
whereas I was hoping for something more like:
first_name role_name
--------------------------------------
Chris employee
Chris admin
Chris exec
Brian employee
Jen employee
Jen exec
...
At tis point I'm not sure if it's my table structure that is flawed or if I'm using joins incorrectly or if it's that plus a bunch of other stuff I don't even know about. Can someone help point me in the right direction?
Stare at this piece of your query: ON Roles.rn_id = Roles.role_id;
It is not what you meant!
Here is the fixed query (with clearer formatting):
SELECT Users.fname, Role_Names.role_name
FROM Users AS u
INNER JOIN Roles AS r ON u.id = r.user_id
INNER JOIN Role_Names AS rn ON rn.rn_id = r.role_id
Tip: Many:many mapping tables (your Roles
) are typically named by the the two things it relates. So I suggest User_Roles
. Then the 3rd table can be simply Roles
. That leads to
SELECT Users.fname, Role_Names.role_name
FROM Users AS u
INNER JOIN User_Roles AS ur ON u.id = ur.user_id
INNER JOIN Roles AS r ON r.rn_id = ur.role_id
You can use DISTINCT
like following.
SELECT DISTINCT Users.fname, Role_Names.role_name from Users INNER JOIN
Roles on Users.id = Roles.user_id
INNER JOIN Role_Names
ON Roles.rn_id = Roles.role_id;
use distinct
with Users as
(
select 1 id, 'Chris' fname, 'Christy' lname
union all
select 2 , 'Brian', 'Bobson' union all
select 3 ,'Jen' , 'Sanders'
),Role_Names as
(
select 1 rn_id, 'admin' role_name
union all
select 2 , 'exec' union all
select 3 , 'employee'
) , Roles as
(
select 1 role_id,1 user_id
union all
select 1,2 union all
select 1,3 union all
select 2 , 3 union all
select 3 , 3 union all
select 3 , 2
) SELECT distinct Users.fname, Role_Names.role_name
from Users left JOIN
Roles on Users.id = Roles.user_id
left JOIN Role_Names
ON Role_Names.rn_id = Roles.role_id
you missed join in your query
JOIN Role_Names ON Roles.rn_id = Roles.role_id -- here both side you use Roles
Try using below query.
SELECT Users.fname, Role_Names.role_name
from Roles RIGHT OUTER JOIN
Users on Users.id = Roles.user_id
INNER JOIN Role_Names
ON Roles_Names.rn_id = Roles.role_id;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.