简体   繁体   中英

MySQL select only unique values

I have two tables.

Clients:

+--------------+-------------+
|   CLIENT_ID  |    LABEL    |
+--------------+-------------+
|          123 |      label1 |
+--------------+-------------+
|          123 |      label3 |
+--------------+-------------+
|          456 |      label1 |
+--------------+-------------+
|          789 |      label2 |
+--------------+-------------+
|          987 |      label2 |
+--------------+-------------+
|          987 |      label4 |
+--------------+-------------+

Managers:

+----+--------------+
| ID |   CLIENT_ID  |
+----+--------------+
|  1 |          123 |
+----+--------------+
|  1 |          456 |
+----+--------------+
|  2 |          456 |
+----+--------------+
|  3 |          789 |
+----+--------------+
|  3 |          987 |
+----+--------------+
|  4 |          789 |
+----+--------------+

I need to select ID from Managers which have only clients with labels "label1" or "label2" and do not have clients with other labels. The resulting output should be like 2 and 4.

I tried to do as

select m.id
from managers m
    join clients c on m.client_id = c.client_id
where c.label in ('label1', 'label2');

but it returns all ids.

Close. Just add aggregation:

select m.id
from managers s join
     clients c
     on m.client_id = c.client_id
where c.label in ('label1', 'label2')
group by m.id
having count(distinct c.label) = 2;

If you want only clients with these two labels, then use:

select m.id
from managers s join
     clients c
     on m.client_id = c.client_id
group by m.id
having count(distinct c.label) = 2;

select m.id
from managers s join
     clients c
     on m.client_id = c.client_id
group by m.id
having count(distinct case when c.label in ('label1', 'label2') then c.label end) = 2 and
       count(distinct c.label) = 2;

Or, more efficiently:

having sum(c.label = 'label1') > 0 and
       sum(c.label = 'label2') > 0 and
       sum(c.label not in ('label1', 'label2')) = 0;

use group by as follows:

select m.id
from managers m
    join clients c on m.client_id = c.client_id
where c.label in ('label1', 'label2')
group by m.id
having count(*) = 1;

Please try group by and having statement here to get unique records

 SELECT ID FROM `Clients` c 
  left join Managers m on (c.client_id = m.CLIENT_ID) 
  where LABEL in ('label1', 'label2') 
  group by ID having count(*) = 1

Thanks

You can use a CTE to get the number of occurrences where client labels associated with a particular manager are valid:

with r as (select m.id id, sum(c.label in ('label1', 'label2')) c1, count(*) c2 
           from managers m join clients c on m.client_id = c.client_id group by m.id)
select id from r where c1 = c2;

Output:

id
2
4

Join the tables, group by manager and use conditional aggregation for your conditions in the HAVING clause:

SELECT m.id
FROM managers m INNER JOIN clients c 
ON m.client_id = c.client_id
GROUP BY m.id
HAVING MAX(c.label IN ('label1', 'label2')) = 1
   AND MAX(c.label NOT IN ('label1', 'label2')) = 0

This will also work if a client has both labels 'label1' and 'label2' and may be extended to more labels.

See the demo .
Results:

id
2
4

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