Given one or more owner_ids
(for instance, 2, 4, and 6), I would like to return the list of resources.id
linked to owners
by owners_has_resources
. No problem, I could just do SELECT DISTINCT ohr.resources_id FROM owners_has_resources ohr WHERE ohr.owners_id IN (2,4,6);
Now the part I am stuck on. I would like to return the list of resources.id
the same as above, but exclude any that are also linked to non-deleted owners (as determined by owners.deleted!=true
) where the link is not deleted (as determined by owners_has_resources.deleted!=true
)
It can be assumed that owners.deleted
is true
for all the originally provided owners_ids
(ie 2, 4, 6)
For instance, given owners_ids
2 and 4, I should return resources_id
2 and 3. Note that I meant to say deleted=TRUE
indicates it was deleted, but since answers have been posted that used the previous, I won't be editing the question. Instead, the truth table below shows owner_not_deleted
and resource_not_deleted
.
+-----------+-------------------+--------------+----------------------+
| owners_id | owner_not_deleted | resources_id | resource_not_deleted |
+-----------+-------------------+--------------+----------------------+
| 2 | FALSE | 1 | TRUE |
| 2 | FALSE | 2 | TRUE |
| 4 | FALSE | 2 | TRUE |
| 4 | FALSE | 3 | TRUE |
| 5 | TRUE | 1 | FALSE |
| 5 | TRUE | 2 | TRUE |
| 7 | TRUE | 2 | FALSE |
+-----------+-------------------+--------------+----------------------+
owners
- id (INT PK)
- name, etc
- deleted (true/false)
resources
- id (INT PK)
- name, etc
owners_has_resources
- owners_id (INT PK REFERENCES owners.id)
- resources_id (INT PK REFERENCES resources.id)
- deleted (true/false)
What about
SELECT DISTINCT ohr.resources_id
FROM owners_has_resources ohr
JOIN owners o ON ohr.owners_id = o.id
WHERE ohr.owners_id IN (2,4,6)
AND (o.deleted = FALSE OR ohr.deleted = FALSE);
First you pick the data you want then you only select those which are not referenced by non deleted owners in the NOT EXISTS
block
SELECT DISTINCT ohr.resources_id
FROM owners_has_resources ohr
JOIN owners o ON ohr.owners_id = o.id
WHERE ohr.owners_id IN (2,4,6)
AND NOT EXISTS (
SELECT NULL FROM owners_has_resources ohr2
JOIN owners o2 ON ohr2.owners_id = o2.id
WHERE ohr2.deleted=FALSE
AND o2.deleted=FALSE
AND ohr.resources_id=ohr2.resources_id
)
SELECT DISTINCT ohr1.resources_id
FROM owners_has_resources ohr1
LEFT OUTER JOIN owners_has_resources ohr2 ON ohr2.resources_id=ohr1.resources_id AND ohr2.deleted = TRUE
LEFT OUTER JOIN owners o ON o.id=ohr2.owners_id AND ohr2.deleted = TRUE
WHERE ohr1.owners_id IN (2,4,6) AND o.id IS NULL;
or
SELECT DISTINCT ohr1.resources_id
FROM owners_has_resources ohr1
LEFT OUTER JOIN owners_has_resources ohr2 ON ohr2.resources_id=ohr1.resources_id
LEFT OUTER JOIN owners o ON o.id=ohr2.owners_id
WHERE ohr1.owners_id IN (2,4,6) AND o.id IS NULL AND ohr2.deleted = TRUE AND ohr2.deleted = TRUE;
I would appreciate any comments on whether one approach is better than the other.
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.