I think this is a simple SQL query problem, but I am just not familiar enough with the different SQL join types to get the best solution to this problem.
I have a system that manages various items and the owners of those items. A user of the system has access to view all information about the items and the owners of such items if the user has permissions to view that owner. My schema looks like:
Users:
| UserId |
Items:
| ItemId | OwnerId | Name | Age |
Owners:
| OwnerId | FirstName | LastName | State |
OwnerPermissions:
| UserId | OwnerId |
It is possible that an Item does not have an owner — then OwnerId is NULL for that row in the Items table.
So if an entry exists for UserId=0 and OwnerId=0 and OwnerId=1 in OwnerPermissions then UserId=0 can view all the item information owned by OwnerId 0 and 1.
I want to write a query that given a userId, it returns all Item and Owner information for the owners the user has permissions to see, and also shows all items that don’t have owners
The query:
select Items.*, Owners.*
from Items
inner join Owners on Items.OwnerId = Owners.OwnerId
inner join OwnerPermissions on OwnerPermissions.OwnerId = Owners.OwnerId
where OwnerPermissions.UserId = $userId
Gets me all the Item information that are owned by people I have permission to see, but it misses the Items that are not owned by anyone (OwnerId is NULL).
What is the best way to write this query? I use SQL Server, but I prefer an answer that doesn’t rely on it (but would be interested if there is a neat trick SQL Server can do)
Change it to a
LEFT JOINand every item is shown, withNULLif it has no owner.