简体   繁体   中英

How to query a proper subset using MySQL?

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
           );
SELECT a.name
FROM (
    SELECT id,name,group_concat(dept) AS dept
    FROM tab
    GROUP BY id
) AS a
JOIN (
    SELECT id,name,group_concat(dept) AS dept
    FROM tab
    GROUP BY id
) AS b ON b.dept LIKE concat(a.dept,',%')

在此处输入图片说明

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM