TransWikia.com

Obtener ultimo registro guardado en una tabla con relación 1 a N

Stack Overflow en español Asked by Juan Pinzón on September 30, 2020

Tengo las siguientes tablas:

EMPLEADO

ID |NOMBRE | APELLIDO 
1  |TEST   | TEST     
2  |TEST2  | TEST2
3  |TEST3  | TEST3
4  |TEST4  | TEST4

DIRECCION

ID | DIRECCION | EMP_ID | PAIS_ID |FECHA_INSERCION
1  | DIR1      | 1      | 1       |10/10/2019 08:00:00
2  | DIR2      | 1      | 1       |10/10/2019 08:15:00
3  | DIR3      | 1      | 5       |10/10/2019 08:20:00

Quiero obtener la ultima direccion registrada del empleado

por ejemplo

TEST   | TEST  | DIR1 | 5 | 10/10/2019 08:20:00

He intentado la siguiente consulta

Select Nombre,Apellido, Pais_ID, DIRECCION, MAX(FECHA_INSERCION)
FROM EMPLEADO EMP
INNER JOIN DIRECCION DIR ON EMP.ID = DIR.EMP_ID
GROUP BY Nombre, Apellido, Pais_ID, DIRECCION

Sin embargo esto me obtiene lo siguiente:

TEST   | TEST  | DIR1 | 1 | 10/10/2019 08:15:00
TEST   | TEST  | DIR1 | 5 | 10/10/2019 08:20:00

Como podría arreglar la consulta para obtener lo que necesito?

2 Answers

No me queda del todo claro si buscas un caso en particular o las últimas direcciones de todos los empleados, si es esto último, puedes pivotear con una subconsulta que te de la última fecha por cada empleado:

SELECT  EMP_ID,
        MAX(FECHA_INSERCION) as 'ULTIMA_FECHA_INSERCION'
    FROM DIRECCION DIR 
    GROUP BY EMP_ID

Esta la incorporas a tu propia consulta para filtrar solo las filas dónde FECHA_INSERCION = ULTIMA_FECHA_INSERCION. Algo así:

SELECT  EMP.Nombre, 
        EMP.Apellido, 
        DIR.Pais_ID, 
        DIR.DIRECCION, 
        DIR.FECHA_INSERCION
    FROM EMPLEADO EMP
    INNER JOIN DIRECCION DIR 
        ON EMP.ID = DIR.EMP_ID
    INNER JOIN (SELECT  EMP_ID,
                MAX(FECHA_INSERCION) as 'ULTIMA_FECHA_INSERCION'
                FROM DIRECCION
                GROUP BY EMP_ID
        ) U
        ON U.EMP_ID = EMP.ID
        AND U.ULTIMA_FECHA_INSERCION = DIR.FECHA_INSERCION

Por el contrario, si buscas un único caso, la forma natural sería ordenar por FECHA_INSERCION descendente y quedarte con la primera de las filas. Lamentablemente Oracle en versiones anteriores a la 12c no tiene clausula de limitación de filas como otros gestores, así que el truco, es materializar un número de fila según el orden en una subconsulta y filtrar el primero

SELECT  *
    FROM (Select Nombre, 
                 Apellido, 
                 Pais_ID, 
                 DIRECCION, 
                 FECHA_INSERCION,
                 ROWNUM RN
            FROM EMPLEADO EMP
            INNER JOIN DIRECCION DIR 
                ON EMP.ID = DIR.EMP_ID
            WHERE EMP.ID = 1
            ORDER BY FECHA_INSERCION DESC
    ) T
    WHERE T.RN = 1

Otra forma similar a la anterior, es usar la función ROW_NUMBER() para numerar

ROW_NUMBER() OVER (PARTITION BY EMP.ID ORDER BY DIR.FECHA_INSERCION)  RN

Para generar el número de fila, la ventaja que generas un numerador único por cada empleado, por lo que en definitiva, podrías resolver la consulta para todos, usando el mismo filtro: WHERE T.RN = 1

Notas:

  • El rownum se resuelve luego del order después del where por eso es necesario usar una subconsulta para materializar este número de fila
  • Aclaración con la primer consulta, ésta, no evita el problema de filas con idéntica fecha para un mismo empleado, en ese caso te recuperará todas las coincidentes.

Correct answer by Patricio Moracho on September 30, 2020

Te faltaría agregar un TOP 1 para que te devuelva solo un valor (en Oracle es con rownum) y además, añadir un ORDER BY para que te los ordene de mayor a menor fecha, de esa manera el top 1 siempre será el de FECHA_INSERCIÓN más alto:

Select Nombre,Apellido, Pais_ID, DIRECCION, MAX(FECHA_INSERCION)
    FROM EMPLEADO EMP
    INNER JOIN DIRECCION DIR ON EMP.ID = DIR.EMP_ID
    GROUP BY Nombre, Apellido, Pais_ID, DIRECCION
    ORDER BY MAX(FECHA_INSERCION) DESC
where rownum = 1

Answered by kilianbs on September 30, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP