Tengo una mesa como esta:
ID | Val | Kind
----------------------
1 | 1337 | 2
2 | 1337 | 1
3 | 3 | 4
4 | 3 | 4
Quiero hacer un SELECT
que devuelva solo la primera fila para cada uno Val
, ordenando por Kind
.
Salida de muestra:
ID | Val | Kind
----------------------
2 | 1337 | 1
3 | 3 | 4
¿Cómo puedo construir esta consulta?
oracle
greatest-n-per-group
BrunoLM
fuente
fuente
ORDER BY ID DESC
, pero eso no es relevante para la pregunta. En este ejemplo no me importa.Respuestas:
Esta solución también utiliza
keep
, peroval
ykind
también puede ser simplemente calculado para cada grupo sin una subconsulta:dbfiddle aquí
MANTENER ... PRIMERO y MANTENER ... ÚLTIMO son una característica específica de Oracle de los agregados; puede leer sobre esto aquí en los documentos de Oracle, o en ORACLE_BASE :
fuente
Use una expresión de tabla común (CTE) y una función de ventana / clasificación / partición como ROW_NUMBER .
Esta consulta creará una tabla en memoria llamada ORDERED y agregará una columna adicional de rn que es una secuencia de números del 1 al N. PARTITION BY indica que debe reiniciarse en 1 cada vez que el valor de Val cambia y queremos ordenar filas por el valor más pequeño de Kind.
El enfoque anterior debería funcionar con cualquier RDBMS que haya implementado la función ROW_NUMBER (). Oracle tiene una funcionalidad elegante como se expresa en la respuesta de mik que generalmente rendirá mejor rendimiento que esta respuesta.
fuente
La solución de bilinkc funciona bien, pero pensé en tirar la mía también. Tiene el mismo costo, pero podría ser más rápido (o más lento, no lo he probado). La diferencia es que usa First_Value en lugar de Row_Number. Como solo estamos interesados en el primer valor, en mi opinión es más sencillo.
Datos de prueba.
Si lo prefiere, aquí está el equivalente CTE.
fuente
id
sean únicas.Puede usar
keep
para seleccionar unoid
de cada grupo:dbfiddle aquí
fuente
fuente