I have User to Role table with Many to Many relation. I need to retrieve all the roles which are not privileged(false) to any VIP users or it should be Privileged only to VIP users.
I came up with a query using aggregation and bool_or() but my result set has opt4 role. opt4 role should be ignored since its Privileged to a non- vip user (user2 - line item 6)
select
r.rolename
from
pam."role" r
join pam.user_role ur on
r.id = ur.role_id
join pam.user u on
ur.user_id = u.id
group by
r.rolename,
u.vip_flag
having
(not bool_or(ur.privileged)) or u.vip_flag=true;
Any help is much appreciated
Sounds like you simply have to add it to the HAVING clause:
HAVING ((not bool_or(ur.privileged)) OR u.vip_flag=true)
AND rolename <> 'opt4'
Related
Good evening,
I have been struggling with what I think should be a fairly basic SQL query, but I can't seem to figure it out. Particularly because it seems as if there are multiple approaches (joins/ sub-queries).
I have three primary tables, and two tables connecting them.
USER
uID - PK
name, email, ...
GROUP
gID - PK
name
ROLE
rID - PK
permission
USERGROUP
uID - FK
gID - FK
GROUPROLE
gID - FK
rID - FK
These are many to many relationships, such that a user can be in multiple groups, and a group can have multiple roles.
I would like to have a query that ultimately gives me all of the roles that are connected to a given user through the groups that he belongs. Thus the uID is known, but nothing else. The output could have as few as one column with the rID, as that is all I really need for the program logic.
Is it possible to perform a query on the result of a previous query? I can easily find all the groups a user is in, and given each group, I can easily find the roles associated, but I get tripped up by the fact that there are many groups associated with a user, not just a single one which would be easier.
I would appreciate any help!
Thanks in advance.
This is just joins and aggregation:
select array_agg(distinct r.permission) as permissions
from usergroups ug join
grouproles gr
on ug.gid = gr.gid join
roles r
on gr.rid = r.id
where ug.uid = ?;
If you want the permissions in separate rows, then:
select distinct r.permission
from usergroups ug join
grouproles gr
on ug.gid = gr.gid join
roles r
on gr.rid = r.id
where ug.uid = ?;
I am leaving the distinct because different groups could share the same permissions.
I need a query to see which Roles users have in DotNetNuke.
I found this query but it gives the RoleID and not the name.
What if there are more than one role associated to a user?
SELECT Users.FirstName, Users.LastName, Users.Email,UserRoles.RoleID
FROM UserRoles
INNER JOIN Users ON UserRoles.UserID = Users.UserID
You need to include the Roles table in your query if you want the Role Names.
SELECT Users.FirstName, Users.LastName, Users.Email, UserRoles.RoleID, Roles.RoleName
FROM UserRoles
INNER JOIN Users ON UserRoles.UserID = Users.UserID
INNER JOIN Roles ON UserRoles.RoleID = Roles.RoleID
WHERE (Roles.PortalID = 0)
You also might want to include the PortalID to avoid duplicates from other portals. However I would recommend to use the DNN core functionalities do determine a user role, with the RoleController.
If there are 2 roles for a user it will bring 2 rows for the same user with different RoleID. n rows for n roles.
I need help with a query to get All Permissions for a User.
A User can be be in 0-many Groups
Groups can have 0-many Users
A Group can have 0-many Roles
A Role can be in 0-many Groups
A Role can have 0-many Permissions
Permission can be on 0-many Roles
I have a User ID and I need to get all permissions for that User. So I need to get all the groups for a user ID, all the roles for each group for the user, and then all the permissions for the various roles.
I'm fine with the single many to many relationship query, but can seem to manage this nested query.
Example of my single many to many query:
SELECT [Permission].*
FROM [Permission] INNER JOIN
Roles_Permissions ON Permission.PermissionID = Roles_Permissions.PermissionID INNER JOIN
Role ON Roles_Permissions.RoleID = Role.RoleID
WHERE (Role.RoleID = 5)
Assuming the tables available and their structures follow the scheme suggested by permission-role_permissions-role, you can achieve what you want with a query like this:
SELECT p.*
FROM [Permission] p
JOIN Roles_Permissions rp
ON p.PermissionID = rp.PermissionID
JOIN Group_Roles gr
ON rp.RoleID = gr.RoleID
JOIN User_Groups ug
ON gr.GroupID = ug.GroupID
WHERE ug.UserID = /*desired UserID*/
Actually you don't need to join the User, Group and Role tables, because all you need from those entities is the binding between their IDs, that are already available on the relationship tables.
thanks for viewing this. I have a db that has users, roles & user_roles.
What I am trying to achieve is a login that will select users who have Admin or Associate permissions. The login then uses name and password to permit access.
My SQL syntax thus far is -
SELECT * FROM users
LEFT JOIN ON user_roles
ON user.id=user_roles.userid AND roleid IN (Administrator, Associate)
WHERE username = '$username' AND password = '$password'";
I am not sure where I am going wrong.
Thanks in advance for your help.
Try replacing "LEFT JOIN" by "INNER JOIN"
Here's how I'd write the query:
$stmt = $pdo->prepare("
SELECT (u.password = :password) AS password_is_correct,
(r.roleid IS NOT NULL) AS role_is_authorized
FROM users u
LEFT JOIN ON user_roles r
ON u.id=r.userid AND r.roleid IN (Administrator, Associate)
WHERE u.username = :username");
$stmt->execute(array(":password"=>$password, ":username"=>$username));
This allows you to distinguish between the three conditions: (1) username does not exist, (2) password is wrong, or (3) role is not authorized.
PS: Should "Administrator" and "Associate" be quoted or something? The way you're using them, they look like identifiers rather than values.
I am using SQL Server 2005. I have three tables - Users, Groups, and GroupUsers. GroupUsers contains the two PKs for a many-to-many relationship.
I have a view to get all the user information for a group as follows:
SELECT * FROM GroupUsers JOIN Users ON GroupUsers.UserID = Users.UserId
I want to create the inverse of this view - I want a list of all of the users NOT attached to a specific group. The following query would accomplish this:
SELECT * FROM Users WHERE UserID NOT IN
(SELECT UserID FROM GroupUsers WHERE GroupID=#GroupID)
However I don't want to have to specify the group, I want to know how to turn this into a view that joins the GroupID and then the UsersID and all the user info, but only for non-attached users.
I'm not sure how to do this, maybe something with the EXCEPT operator?
UPDATE:
I think this is my solution, unless someone comes up with something better:
SELECT
G.GroupId,
U.*
FROM
Groups G
CROSS JOIN
Users U
WHERE
U.UserId NOT IN
(
SELECT
UserId
FROM
GroupUsers
WHERE
GroupId=G.GroupId
)
You can use a left outer join to grab all of the users, then, blow away any user where there's a group attached. The following query will give you just the list of users where there's no group to be had:
select
u.*
from
users u
left outer join groupusers g on
u.userid = g.userid
where
g.userid is null
If you want to find all users not in a particular group:
select
u.*
from
users u
left outer join groupusers g on
u.userid = g.userid
and g.groupid = #GroupID
where
g.userid is null
This will only exclude the users in that particular group. Every other user will be returned. This is because the groupid condition was done in the join clause, which limits the rows joined, not returned, which is what the where clause does.
If I understand it correctly, you will have to do a cartersian result of users & groups and reduce the result derived from GroupUsers.
That will give you records of users which do not have any groups attached to it.
I apologize if I didn't understand the question correctly.
EDIT: Cartesian result will give you users * groups. You will have to subtract GroupUsers from it. I am sorry, I do not have SQL ready for it & can't try it out at this point.
I couldn't figure out how to get previous version to work via active record, got some of the way there but had to write an SQL in statement. I believe this also accomplishes the same thing.
SELECT * FROM Users WHERE UserID NOT IN
(SELECT U.UserID FROM GroupUsers AS G, Users as U WHERE G.UserID <> U.UserID)
Couldn't test however this query in rails worked just fine:
# Gets Pre-Clients. Has client information but no project attached
Contact.joins(:client).includes(:projects => :primary_contact).
where("contacts.id NOT IN (select contacts.id from contacts,
projects where projects.primary_contact_id = contacts.id)")
Thanks for the post got me 90% of the way there.