Pergunta

Como eu poderia ser capaz de obter resultados N por vários grupos na uma consulta Oracle.

Por exemplo, dada a tabela a seguir:

|--------+------------+------------|
| emp_id | name       | occupation |
|--------+------------+------------|
|      1 | John Smith | Accountant |
|      2 | Jane Doe   | Engineer   |
|      3 | Jack Black | Funnyman   |
|--------+------------+------------|

Existem muitas linhas mais com mais ocupações. Eu gostaria de obter três funcionários (digamos) de cada ocupação.

Existe uma maneira de fazer isso sem usar uma subconsulta?

Foi útil?

Solução

Isso produz o que você quer, e não utiliza recursos do SQL específicos do fornecedor como TOP N ou RANK ().

SELECT MAX(e.name) AS name, MAX(e.occupation) AS occupation 
FROM emp e 
  LEFT OUTER JOIN emp e2 
    ON (e.occupation = e2.occupation AND e.emp_id <= e2.emp_id) 
GROUP BY e.emp_id 
HAVING COUNT(*) <= 3 
ORDER BY occupation;

Neste exemplo, ele dá os três funcionários com os valores mais baixos emp_id por ocupação. Você pode alterar o atributo usado na comparação de desigualdade, para torná-lo dar os principais funcionários pelo nome, ou o que quer.

Outras dicas

Eu não tenho uma instância Oracle calhar agora, então eu não testei isso:

select *
from (select emp_id, name, occupation,
      rank() over ( partition by occupation order by emp_id) rank
      from employee)
where rank <= 3

Aqui está um link sobre como funciona Rank: http://www.psoug.org/reference /rank.html

Adicionar rowNum a classificação:

select * from 
         (select emp_id, name, occupation,rank() over ( partition by occupation order by emp_id,RowNum) rank   
                      from employee) 
         where rank <= 3 

testado isso em SQL Server (e usa subconsulta)

select emp_id, name, occupation
from employees t1
where emp_id IN (select top 3 emp_id from employees t2 where t2.occupation = t1.occupation)

apenas fazer um ORDER BY na subconsulta para atender às suas necessidades

Eu não estou certo de que este é muito eficiente, mas talvez um ponto de partida?

select *
from people p1
    join people p2
        on p1.occupation = p2.occupation
    join people p3
        on p1.occupation = p3.occupation
        and p2.occupation = p3.occupation
where p1.emp_id != p2.emp_id
    and p1.emp_id != p3.emp_id

Isso deve lhe dar linhas que contêm 3 funcionários distintos tudo na mesma profissão. Infelizmente, ele vai te dar todas as combinações desses.

Pode alguém pare este para baixo por favor?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top