SQL JOIN multiple many-to-many tables - mysql

Using MySql, I will like to join multiple many-to-many tables (users_roles and roles_permissions) by a given user id.
But there is something wrong with my query because it gives an error as below.
#1054 - Unknown column 'users_roles.role_id' in 'on clause'
SELECT roles.name, permissions.name
FROM users_roles, roles_permissions
JOIN roles ON users_roles.role_id = roles.id
JOIN permissions ON roles_permissions.permission_id = permissions.id
WHERE users_roles.user_id = 1 AND roles_permissions.role_id = roles.id
My table structure inside PHPMyAdmin is as follow:
Table users_roles
id | user_id | role_id
Table roles_permissions
id | role_id | permissions_id
Table roles
id | name | description
Table permissions
id | name | description

I think you should use a set of proper join
SELECT roles.name, permissions.name
FROM users_roles
JOIN roles ON users_roles.role_id = roles.id
JOIN roles_permissions on roles_permissions.role_id = users_roles.role_id
JOIN permissions ON roles_permissions.permission_id = permissions.id
WHERE users_roles.user_id = 1

You can use the below query,
You can do it in two ways,
Using JOINS
SELECT roles.name, permissions.name
FROM users_roles INNER JOIN roles_permissions
ON (users_roles.role_id = roles.id)
INNER JOIN permissions ON (roles_permissions.permission_id = permissions.id)
AND users_roles.user_id = 1
AND roles_permissions.role_id = roles.id;
Using Alias
SELECT R.name, P.name from
users_roles UR, roles_permissions RP, permissions P, roles R
WHERE UR.role_id = R.id AND
RP.role_id = UR.role_id AND
RP.permission_id = P.id
UR.user_id = 1;
But using JOINS is the efficient way. Hope you got it. Any help, feel free to ask

Related

Filtering an inner join results

I have four tables.
usuarios
roles
permisos
roles_permisos (pivot table)
I need to get all the users and roles with the permission equal to 2. I'm not good with sql and I don't know how to achieve this.
I guess I need an inner join between users and roles and from there filter the role with permission 2 from the pivot table
SELECT usuarios.nombre, roles.nombre
FROM usuarios
INNER JOIN roles ON roles.id = usuarios.rol_id
http://sqlfiddle.com/#!9/470356/16
PD: sorry, the examples are in spanish
Add another join with roles_permisos
SELECT usuarios.nombre, roles.nombre
FROM usuarios
INNER JOIN roles ON roles.id = usuarios.rol_id
INNER JOIN roles_permisos ON roles.id = roles_permisos.roles_id
WHERE roles_permisos.permisos_id = 2
You can start from the table for the permissions (permisos).
Where the id equals 2, or the name (permiso) equals 'Editar'.
Then join the other tables on the correct id.
Till you get to the table with the users (usuarios)
SELECT
usuarios.nombre AS usuario_nombre
, roles.nombre AS role_nombre
FROM permisos
JOIN roles_permisos
ON roles_permisos.permisos_id = permisos.id
JOIN roles
ON roles.id = roles_permisos.roles_id
JOIN usuarios
ON usuarios.rol_id = roles.id
WHERE permisos.permiso = 'Editar';

Join two table where one table has relation with many table

I have 5 table, and the structure is below --
user - id
- name
- dob
- phone
desi - id
- desgname
- dept_id
dept - id
- deptname
- org_id
org - id
- orgname
junction_table - id
- userid
- desg_id
- dept_id
- org_id
How could I make a joint table?
update
After trying sometime, I got a solution and i posted it as answer
Try this
$this->db->select('your-selection');
$this->db->from('user');
$this->db->join('designation','user.designation_id=designation.designation_id');
$this->db->join('department','user.department_id=department.department_id');
$this->db->join('org','user.org_id=org.org_id');
$this->db->join('designation','user.designation_id=designation.designation_id');
$this->db->where('your-condition`);
$result_set = $this->db->get();
return $result_set->result();
your-selection can be your fields that you want to select.
your-condition can be your conditions in an array.
If I understood well I think you need something like this, join every table to get the info you need.
SELECT
U.name
,D.desgname
,DPT.deptname
,O.orgname
FROM junction_table JT
INNER JOIN [user] U
ON JT.userid = U.id
INNER JOIN [desi] D
ON JT.desg_id = D.id
INNER JOIN [dept] DPT
ON JT.dept_id = DPT.id
INNER JOIN org O
ON JT.org_id = O.id
The Solution is to left join the junction table to user table and then again left join to junction table to other table
SELECT
U.name,
O.orgname,
DPT.dpt,
D.desgname
FROM user U
LEFT JOIN junction_table JT
ON U.id = JT.user_id
LEFT JOIN organization O
ON JT.org_id = O.id
LEFT JOIN tbl_suborg DPT
ON JT.dpt_id = DPT.id
LEFT JOIN designation D
ON JT.desg_id = D.id
Thanks brother for trying to help me.

mysql join with two row into one

I have 2 tables table name is users and projects.the structure of table is:
user table
id | name | role
1 | samjad | user
2 | saneer | constructor
projects table
id | name | user_id | constructor_id |
1 | school | 1 | 2 |
How can i get all details from both table in a single row based on project table id.
i want to select
projectname username, constroctorname, user_id, constroctor_id
in a single row
You can join the user table twice - Once as users and then as constructors.
select p.name as projectname,
u.name as username,
c.name as contructorname,
p.user_id,
p.contructor_id
from projects p
left join user u on p.user_id = u.id
left join user c on p.contructor_id = c.id
where u.role = 'user' -- check if the said user has role "user"
and c.role = 'constructor'; -- check if the said constructor has role "constructor"
Do the fact you have two relation between project table and user (one for user and one for constroctor) You can use user joined for two time
select p.name, u1.username, u2.username, p.user_id, p.constroctor_id
from projects as p
inner join user as u1 on p.user_id = u1.id
inner join user as u2 on p.constroctor_id = u2.id
You can use concat() function:
SELECT CONCAT(field1, field2, field3);
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_concat
or CONCAT_WS(separator,str1,str2,...)
Assuming there is a table called Constructor with columns name and constructor_id your query would be
select
p.name as projectname,
u.name as username,
c.name as constructorname,
u.id as userid,
c.id as constructorid
from
projects p
inner join user u on p.user_id=u.id
inner join constructor c on p.constructor_id=c.id
Use a join. You probably want an INNER JOIN:
SELECT * -- actually include only the fields you need
FROM Projects p
INNER JOIN Users u ON u.id = p.user_id
INNER JOIN Users uc ON uc.id = p.constructor_id
You'll want to join the tables on their keys. In this case something like the below:
select p.name as projectname
, u.name as username
, if(u.role='constructor',u.name,null) as constructorname
, p.user_id, p.constructor_id
from users u
join projects p
on p.user_id = u.id;

SQL query to link two tables returning error

I have two tables as follows
user [ ID , username ]
relationship [ user1_id(FK) , user2_id (FK) , status ]
I am trying to get the username by using either user1_id or user2_id where the status = 1 from relationship table. user1_id and user2_id are both IDs from the user table. The following query is failing and I am not sure where it's going wrong.
SELECT
U.username,
(R.first_user_id, R.second_user_id AS friends)
FROM
user U,
`relationship` R
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id`)
AND (`status` = 1 AND U.ID = friends)
returns both names of users in a relationship with a status of 1.
this also assumes that if a relationship record exists, both users must be in the user table.
SELECT U1.UserName, U2.username
FROM Relationship R
INNER JOIN USER U1
on R.User1_ID = U1.user_ID
INNER JOIN USER U2
and R.User2_ID = U2.user_ID
WHERE R.Status=1
It looks like you may be trying to get the usernames of all users that have a relationship with a certain specified user, regardless of the order of user IDs in the relationship record. That could be this:
SELECT
U.username,
U.first_user_id,
FROM
user U
JOIN `relationship` R
ON R.first_user_id = U.ID
WHERE
(R.`second_user_id` = {$userID})
AND (`status` = 1)
UNION ALL
SELECT
U.username,
U.second_user_id,
FROM
user U
JOIN `relationship` R
ON R.second_user_id = U.ID
WHERE
(R.`first_user_id` = {$userID})
AND (`status` = 1)
If that produces duplicates (or could do) and you don't want it to do, then change the UNION ALL to a straight UNION.
I have succeeded based on xQbert answer:
SELECT
U1.username,
U2.username
AS user_friend
FROM
Relationship R
INNER JOIN
user U1
ON
R.first_user_id = U1.ID
INNER JOIN
user U2
ON
R.second_user_id = U2.ID
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id` = {$userID})
AND `status` = 1

How to construct a command to join 3 different tables in mySQL?

I have three different tables in MySQL:
given an user id, how can i get a list of role's name of this user?
For example, user_id = 1
I need a list like this (1, deleteuser, modifyuser, viewuser)
How can I construct my SQL command to get such a list?
JOIN the three tables like so:
SELECT
u.id,
r.Name
FROM user u
INNER JOIN user_role ur ON u.id = ur.user_id
INNER JOIN roles r ON ur.Role_id = r.id
WHERE u.id = Someid
However, if you want the list of roles for each user to be concatenated into one string. Use GROUP_CONCAT like so:
SELECT
u.id,
GROUP_CONCAT(r.Name) roles
FROM user u
INNER JOIN user_role ur ON u.id = ur.user_id
INNER JOIN role r ON ur.Role_id = r.id
WHERE u.id = 1
GROUP BY u.id
SQL Fiddle Demo
SELECT User_id, Name
FROM User_role
JOIN Role ON User_role.Role_id = Role.Id
WHERE User_id = '1'
that would create a list like this:
User_id | Name
1 | DeleteUser
1 | ModifyUser
1 | ViewUser
Try this:
SELECT User_id, GROUP_CONCAT(r.Name)
FROM User_Role ur
INNER JOIN Role r ON ur.Role_id = r.Role_id
GROUP BY User_id;