Pregunta

¿Cómo podría obtener N resultados para varios grupos en una consulta de oráculo.

Por ejemplo, dada la siguiente tabla:

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

Hay muchas más filas con más ocupaciones. Me gustaría conseguir Tres empleados (digamos) de cada ocupación.

¿Hay una manera de hacer esto sin usar una subconsulta?

¿Fue útil?

Solución

Esto produce lo que desea, y no utiliza características SQL específicas del proveedor como TOP N o 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;

En este ejemplo, da a los tres empleados los valores más bajos de emp_id por ocupación. Puede cambiar el atributo usado en la comparación de desigualdad, para que le dé a los mejores empleados por nombre, o lo que sea.

Otros consejos

No tengo una instancia de Oracle a la mano en este momento, así que no he probado esto:

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

Aquí hay un enlace sobre cómo funciona el rango: http://www.psoug.org/reference /rank.html

Agregar RowNum al rango:

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

probó esto en SQL Server (y usa subconsultas)

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)

simplemente haga un PEDIDO en la subconsulta para satisfacer sus necesidades

No estoy seguro de que esto sea muy eficiente, pero tal vez sea un punto 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

Esto debería darle filas que contengan 3 empleados distintos, todos en la misma ocupación. Desafortunadamente, te dará TODAS las combinaciones de esas.

¿Alguien puede reducir esto por favor?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top