I have to filter records from the table for those employees whose role is both -21 and -24.
EX: in the give example emp_id 2, it has role defined -21 as well as -24. this needs to be filtered out.
input data:
EMP_ID ROLE_ID
1 -21
1 -31
1 -81
2 -21
2 -24
3 -24
3 -31
3 -42
expected output
EMP_ID ROLE_ID
1 -21
1 -31
1 -81
3 -24
3 -31
3 -42
One possibility is the following:
SELECT *
FROM DAT d
WHERE emp_id NOT IN (SELECT emp_id
FROM dat
WHERE role_id IN (-21,-24)
GROUP BY emp_id
HAVING COUNT(*) = 2)
Given your data:
WITH dat (emp_id, role_id) AS ( select 1, -21 from dual union all
select 1, -31 from dual union all
select 1, -81 from dual union all
select 2, -21 from dual union all
select 2, -24 from dual union all
select 3, -24 from dual union all
select 3, -31 from dual union all
select 3, -42 from dual)
SELECT *
FROM DAT d
WHERE emp_id NOT IN (SELECT emp_id
FROM dat
WHERE role_id IN (-21,-24)
GROUP BY emp_id
HAVING COUNT(*) = 2)
It leeds to:
EMP_ID ROLE_ID
1 -21
1 -31
1 -81
3 -24
3 -31
3 -42
as required.
You can do it in several ways (grouping, not exists etc). I think that the fastest way is analytical count():
select emp_id, role_id
from (
select emp_id, role_id,
count(case role_id when -21 then 1 end) over (partition by emp_id) c21,
count(case role_id when -24 then 1 end) over (partition by emp_id) c24
from input )
where c21 = 0 or c24 = 0
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.