I have an SQL query that selects user’s privileges, and adds true to them.
SELECT
PrivilageName,
'true' hasrights <-- imaginary column
FROM
users
NATURAL JOIN usermemberships
NATURAL JOIN groupprivileges
NATURAL JOIN `privileges`
WHERE
UserID = '2'
Result is
AddBuilding true
RemoveBuilding true
EditBuilding true
I’m trying to add the rest of the privilages with false value.
AddBuilding true
RemoveBuilding true
EditBuilding true
RemoveUser false
AddUser false
How I’ll do this?
Edit: the structure of the tables:
users(UserID),
usermemberships(UserID, groupID),
groupprivileges(GroupID, PrivilegeID),
privileges(PrivilegeID, PrivilageName)
Edit: misspelling, sorry.
(NOTE: The queries in this answer are now updated, to include the column names that were added to the question.)
One approach to getting that resultset would be to use
LEFT JOINoperations (with appropriate predicates in theONcaluse), in place of all thoseNATURAL JOINoperations.(I’m just guessing at the column names referenced by the
NATURAL JOIN. In order to decipher that, we would need to inspect each table definition to get a list of all of the columns, and then find all the column names that match, to figure out which columns MySQL is using to do those inner join operations.)Based on the scant information provided in the query text, here’s the approach I would take (again, just guessing at the names referenced in each ON clause):
Depending on the cardinality in those tables (i.e. is “AddBuilding” privilege granted to two different groups, one which the user is a member of and the other not…)
and depending on whether you want to avoid returning any “duplicate”
PrivilageNamevalues (either multiple rows with “true” or “false”, or rows with both “true” and “false” for each PrivilageName), and depending on how you want the resultset ordered (i.e. do you want all the “true” privileges listed first?)…Then this query is more deterministic in the resultset that is returned, it will return each PrivilageName only once. This resultset seems better suited to answer the question whether a user has a privilege or not.
(Personally, I’d omit the ORDER BY, and let the results be ordered by PrivilageName, but with the ORDER BY, this better matches the resultset specified in the question.)
Of course, that’s not the only way to get the result set, but it’s likely to be the most efficient (given suitable indexes).
Personally, I don’t ever use
NATURAL JOIN. (I want to see the predicates in the statement, and I don’t want any of my queries to “break” if someone adds a column with a matching name to one of the table in my query. (Actually, thinking about it, I can’t use NATURAL JOIN becauseidis typically the name of the primary key column of nearly all my tables… foreign key columns are typically namedreferencedtable_id.) But even if I did name the columns in a way that I could use NATURAL JOIN, I see the potential drawbacks outweighing any advantage.But, something like the statement below might work. (I say “might” because I don’t have any experience using syntax like this… I never use NATURAL JOIN, and I always prefer LEFT joins to RIGHT joins. If someone in my shop came to me with this, I would give them the statement above. But I don’t want to leave you with the impression that a
NATURAL JOINcan’t be used to return the specified resultset. It’s possible your specified resultset might be returned by a statement like this: