найти записи, которые существуют только для 2 значений - PullRequest
1 голос
/ 05 апреля 2020

У меня есть Структура таблицы / Набор данных выглядит следующим образом.

Emp_id  Expense_amt_dollar  Dept
1111    100                 Marketing    
1111    75                  Finance
1111    25                  IT
2222    100                 Marketing
3333    50                  Finance
4444    30                  Marketing
4444    70                  Finance
5555    200                 IT

O / PI ищет расходы Emp только в 2 отделах

Emp_id  Expense_amt_dollar  Dept
1111    100                 Marketing
1111    75                  Finance
4444    30                  Marketing
4444    70                  Finance

Emp, в которых есть записи для этих Только 2 отдела Записи должны быть на оба отдела.

Ответы [ 5 ]

1 голос
/ 05 апреля 2020

Другим вариантом будет создание подзапроса с предложением having count(distinct dept) = 2, а затем соединение с той же таблицей.

select t1.*
  from tab t1
  join (select emp_id, max(dept) dept1, min(dept) dept2
          from tab
         where dept in ('Finance', 'Marketing')
         group by emp_id
        having count(distinct dept) = 2) t2
    on t1.emp_id = t2.emp_id
   and t1.dept in (t2.dept1, t2.dept2)
1 голос
/ 05 апреля 2020

Emp, который имеет записи только для этих 2 отделов. Записи должны иметь как для отдела.

Я бы использовал оконные функции:

select emp_id, expense_amt_dollar, dept
from (
    select 
        e.*, 
        sum(case when dept in ('Marketing', 'Finance') then 1 end) over(partition by emp_id) cnt_deps
        sum(case when dept not in ('Marketing', 'Finance') then 1 end) over(partition by emp_id) cnt_other_deps
    from emp e
) e
where cnt_deps = 2 an cnt_other_deps is null

Это дает вам записи для сотрудников, принадлежащих к обоим отделам и для другого отдела нет - вот как я понимаю твой вопрос. Для этого вам нужно просмотреть всю таблицу: фильтрация с помощью предложения where не позволит вам проверить, что сотрудник не принадлежит ни к какому другому отделу.

1 голос
/ 05 апреля 2020

С EXISTS:

select t.* from tablename t
where t.dept in ('Finance', 'Marketing')
and exists (
  select 1 from tablename
  where emp_id = t.emp_id and dept in ('Finance', 'Marketing') and dept <> t.dept
)

или с CTE:

with cte as (
  select t.* from tablename t
  where t.dept in ('Finance', 'Marketing')
)
select c.* from cte c
where exists (
  select 1 from cte 
  where emp_id = c.emp_id and dept <> c.dept
)

См. Демоверсию . Результаты:

> EMP_ID | EXPENSE_AMT_DOLLAR | DEPT     
> -----: | -----------------: | :--------
>   1111 |                 75 | Finance  
>   1111 |                100 | Marketing
>   4444 |                 70 | Finance  
>   4444 |                 30 | Marketing
0 голосов
/ 06 апреля 2020

Работал в Postgresql:

select * 
from employee_expenses
where emp_id in 
(
select emp_id from employee_expenses 
where dept = 'Finance'
intersect
select emp_id from employee_expenses
where dept ='Marketing'
)
and dept in ('Finance', 'Marketing');
0 голосов
/ 05 апреля 2020

Вы можете выбрать строки маркетинга и финансов, а затем проверить, получаете ли вы оба для сотрудника:

select *
from
(
  select emp_id, dept, count(*) over (partition by emp_id) as cnt
  from mytable t
  where dept in ('Marketing', 'Finance')
)
where cnt = 2
order by emp_id, dept;
...