简体   繁体   中英

Pull data from table based on role id

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

demo

Try below query:

select * from Y where emp_id in (select  emp_id from(
select emp_id, count(emp_id) c from Y where role_id in ('-21','-24') 
group by emp_id) where c != 2
);

输出

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