I'll give a simple example of what I mean, but essentially I want to select all entries in a table that are proper subsets of some other entry for that table. For example, here is a table
+----+---------------+------------+
| id | name |department |
+----+---------------+------------+
| 1 | John Smith | 1 |
| 1 | John Smith | 2 |
| 2 | Sally Thomas | 3 |
| 2 | Sally Thomas | 4 |
| 3 | Jimmy John | 1 |
| 3 | Jimmy John | 2 |
| 3 | Jimmy John | 3 |
| 4 | Tom Roberts | 3 |
| 4 | Tom Roberts | 4 |
+----+---------------+------------+
From that table, I would only want to select John Smith. The reason is because the departments that John Smith works at are completely contained by the departments that Jimmy John works at. The departments that Sally Thomas works at are identical to the ones Tom Roberts works at, so they do not contain each other. I'm using this definition of a proper subset. How could I write an SQL statement to cover this? Thanks!
Hmmmm . . . This seems like a self-join, but one where the counts could be quite useful:
select t1.name, t2.name
from t t1 join
t t2
on t1.department = t2.department join
(select name, count(*) as cnt
from t
group by name
) t1name
on t1.name = t1name.name join
(select name, count(*) as cnt
from t
group by name
) t2name
on t2.name = t2name.name
group by t1.name, t2.name
having count(*) = t2name.cnt and -- have everything in t2
t2name.cnt < t1name.cnt; -- strict subset
Hmmm, another method uses group_concat()
:
select t1.name, t2.name
from t t1 join
t t2
on t1.department = t2.department
group by t1.name, t2.name
having group_concat(t2.department order by t2.department) =
(select group_concat(t.department order by t.department)
from t
where t.name = t2.department
);
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.