Oracle 12c - выбрать строки с несколькими значениями в группе - PullRequest
0 голосов
/ 28 сентября 2018
select ssn, count(*) 
from (
  select ssn, employee_id, is_active 
  from employee 
  where is_active ='Y'
)
group by ssn
having count(*) > 1

Я хочу изменить этот запрос, чтобы найти все ssn, которые существуют в таблице более одного раза, НО с разными employee_id, по крайней мере с одной записью, имеющей is_active Y.

Ответы [ 4 ]

0 голосов
/ 28 сентября 2018

Никаких подзапросов или CTE не требуется, просто group by и having:

select ssn, count(*) 
from employee
group by ssn
having min(employee_id) <> max(employee_id) and
       sum(case when is_active ='Y' then 1 else 0 end) >= 1;
0 голосов
/ 28 сентября 2018

Если вам нужны все детали, то:

SELECT ssn,
       employee_id,
       is_active 
FROM   (
  SELECT ssn,
         employee_id,
         is_active,
         COUNT( DISTINCT employee_id ) OVER ( PARTITION BY ssn ) AS num_emps,
         COUNT( CASE is_active WHEN 'Y' THEN 1 END ) OVER ( PARTITION BY ssn )
           AS num_active
  FROM   employee
)
WHERE  num_emps > 1
AND    num_active > 0

Если вы просто хотите ssn s, тогда:

SELECT ssn
FROM   employee
GROUP BY ssn
HAVING COUNT( DISTINCT employee_id ) > 1
AND    COUNT( CASE is_active WHEN 'Y' THEN 1 END ) > 0;
0 голосов
/ 28 сентября 2018

Если я правильно понимаю, это должно сделать

select TMP.*
from (
  select CASE WHEN MIN(employee_id) OVER( PARTITION BY ssn) <>
                   MAX(employee_id) OVER( PARTITION BY ssn) THEN 'Y'
              ELSE 'N'
          END AS hasMultipleDistinctEmployees,
         CASE WHEN MAX(CASE WHEN is_active = 'Y' THEN 1 ELSE 0 END) OVER
                     ( PARTITION BY ssn ) = 1 THEN 'Y' 
              ELSE 'N'
          END AS hasAtLeaseOneActive,
  ssn, employee_id, is_active 
  from employee 
) TMP
WHERE hasMultipleDistinctEmployees = 'Y'
  AND hasAtLeaseOneActive = 'Y'
0 голосов
/ 28 сентября 2018

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

WITH cte AS(
  select ssn, employee_id,
   COUNT(DISTINCT employee_id) OVER(PARTITION BY ssn) AS cnt,
   SUM(CASE WHEN is_active ='Y' THEN 1 ELSE 0 END) OVER(PARTITION BY ssn) AS s_active
  from employee 
)
SELECT *
FROM cte
WHERE cnt > 1 AND s_active > 1;
...