简体   繁体   中英

sql only return rows that have certain column values

在此处输入图像描述

With my tables above how can I return the user_id (s) which belong to companies that are only in type_id = 34 and 35 and not belonging in type_id = 8. So since comp_id = 3 isnt in type_id = 8 and is in type_id = 34 and 35 therefore results should be user_id =104 and 105

Im looking for users who are in companies both type_id =34 and 35 not either or. If it is not in 34 but in 35 then users from that company should not be returned.

You can use conditional aggregation to get the comp_id s that meet your conditions and with the operator IN get the user_id s:

select user_id 
from Table_2
where comp_id in (
  select comp_id
  from Table_1
  group by comp_id
  having sum(type_id not in (34, 35)) = 0
     and sum(type_id in (34, 35)) = 2
)

If there are other type_id s than 34, 35 and 8 and they are also allowed as long as 34 and 35 exist but not 8 then:

select user_id 
from Table_2
where comp_id in (
  select comp_id
  from Table_1
  group by comp_id
  having sum(type_id = 8) = 0
     and sum(type_id in (34, 35)) = 2
)

This is a simple and readable way to do it.

SELECT DISTINCT user_id 
FROM Table_2
WHERE comp_id IN (
    SELECT DISTINCT comp_id
    FROM Table_1
    WHERE type_id IN (34, 35)
    MINUS
    SELECT DISTINCT comp_id
    FROM Table_1
    WHERE type_id IN (8)
)

If your database doesn't support SELECT DISTINCT then just use SELECT and add a GROUP BY comp_id to the bottom of each SELECT statement. Capitalisation of keywords is optional. If you already have a big WHERE statement for Table_2 you can use an inner join to the sub-select instead of an IN.

-- EDIT: to avoid the use of MINUS for MySQL --
Confession: I'm not able to test this SQL in MySQL at the moment

SELECT DISTINCT Table_2.user_id 
FROM Table_2
INNER JOIN
     (SELECT DISTINCT comp_id
      FROM Table_1
      WHERE type_id IN (34, 35)
     ) type_include ON Table_2.type_id = type_include.type_id
LEFT JOIN
     (SELECT DISTINCT comp_id
      FROM Table_1
      WHERE type_id IN (8)
     ) type_exclude ON Table_2.type_id = type_exclude.type_id
                   AND type_exclude.type_id IS NULL

You can do such a thing with a subquery, in which you specify the condition that should not be met

SELECT DISTINCT t2.user_id 
    FROM Table_2 t2 
JOIN Table_1 t1 
    ON ((t1.comp_id = t2.comp_id) 
      AND ((type_id = 34) OR (type_id = 35))
      AND t1.comp_id NOT IN (SELECT comp_id FROM Table_1 WHERE type_id = 8)
    )
;

PS: For the data in your example, you would not even have to check for the ID being equal to 35 or 34 as there are no other values in your data anyway.

SELECT DISTINCT t2.user_id 
    FROM Table_2 t2 
    WHERE t2.comp_id NOT IN (SELECT comp_id FROM Table_1 WHERE type_id = 8)
;

EDIT: As was correctly pointed out, the first query will

  • also include user_ids for which Table_1 only has rows with either type_id = 34 or type_id = 35 and not only with both
  • also include user_ids for which Table_1 has rows that additionally to 34 or 35 may have another type_id other than 8 (which is not present in the example, but may happen in other data)

This is by design, as I understood the question requiring this. If this is not the intended result, please look at the answer from @forpas ( https://stackoverflow.com/a/63382574/14015737 ), which yields a result that does neither of the above.

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