Uso de consultas anidadas en combinación izquierda

Tengo dos tablas emp_master y transfer. para cada employee_id en emp_master puede haber múltiples entradas en la tabla de transferencia. Quiero obtener el registro más reciente de la tabla de transferencia según date_of_tansfer y mostrarlo con datos de emp_master. He escrito una consulta como esta que no funciona. Recibo un error "EMP.EMPLOYEE_ID: identificador no válido". Puedo obtener los detalles de un solo empleado si lo codifico con ese employee_id... pero ¿cómo puedo modificarlo para obtener datos de todos los empleados?

select distinct emp.employee_id,trnsf.OU
from emp_master emp 
left join (select * from (select * from transfer where employee_id = emp.employee_id 
and date_of_transfer <= SYSDATE order by date_of_transfer desc) where rownum = 1) trnsfr
on trnsfr.EMPLOYEE_ID = emp.employee_id


CREATE TABLE "EMP_MASTER" 
   ( "EMPLOYEE_ID" NUMBER(10,0), 
     "FIRST_NAME" VARCHAR2(30 BYTE), 
     "MIDDLE_NAME" VARCHAR2(30 BYTE), 
     "SURNAME" VARCHAR2(30 BYTE), 
   ) 

 CREATE TABLE "TRANSFER" 
   (    "EMPLOYEE_SR_NO" NUMBER, 
        "EMPLOYEE_ID" NUMBER(10,0), 
        "DATE_OF_TRANSFER" DATE, 
        "OU" VARCHAR2(30 BYTE)
 ) 

preguntado el 04 de julio de 12 a las 07:07

2 Respuestas

La razón por la que recibe ese error es el nivel de anidamiento de sus tablas derivadas (subconsultas). Una subconsulta puede "ver" solo las columnas/tablas de la consulta "principal" inmediata (que en su caso es la selección externa que limita el resultado a una fila).

Lo siguiente debería hacer lo que quieras:

select distinct emp.employee_id, trnsfr.ou
from emp_master emp 
left join (
      select transfer.employee_id,
             transfer.ou,
             row_number() over (order by date_of_transfer desc) as rn
      from transfer 
      where date_of_transfer <= SYSDATE 
    ) trnsfr
    on trnsfr.employee_id = emp.employee_id and trnsfr.rn = 1;

If date_of_transfer es realmente una "FECHA" (es decir, sin tiempo involucrado) de lo que podría considerar usar date_of_transfer <= trunc(SYSDATE) en su lugar, para "eliminar" la hora del resultado de SYSDATE.

Respondido 04 Jul 12, 08:07

Lo intenté... pero recibo un error DE palabra clave no encontrada, seleccione *, número de fila () sobre (ordenar por date_of_transfer desc) como rn de hris_transfer_dtl donde employee_id = emp.employee_id y date_of_transfer <= SYSDATE ... esta consulta en sí mismo está dando ese error ... - Andrómeda

el error anterior se debe a ..agregué un alias. y lo hice funcionar ... pero para toda la consulta recibo el mismo error emp.Employee_id identificador no válido ... - Andrómeda

@Jasim: solucioné el error. Faltaba un prefijo para el * y el where employee_id = emp.employee_id no es necesario porque eso es parte de la condición de combinación de todos modos. - un caballo sin nombre

lo intenté... la consulta no está arrojando ningún error ahora... pero los datos que estoy obteniendo no son correctos porque la mayoría del valor de registro para la columna OU es nulo... solo para una fila está saliendo correctamente... - Andrómeda

@Jasim: bueno, eso es de esperar cuando se usa una combinación externa. ¿Está seguro de que tiene al menos una fila para cada employee_id en emp_master - un caballo sin nombre

Intente esta consulta con unión interna y una subconsulta:

SELECT * FROM EMP_MASTER T1 
INNER JOIN TRANSFER T2 ON T1.employee_id =T2.employee_id 
WHERE T2.DATE_OF_TRANSFER=(SELECT MAX(T3.DATE_OF_TRANSFER) FROM TRANSFER T3 WHERE T3.employee_id =T2.employee_id );

Respondido 04 Jul 12, 08:07

esta consulta no funciona en caso de que no haya ningún registro en la tabla de transferencias... quiero completar nulo en caso de que no haya datos... - Andrómeda

Intente esto: SELECCIONE * DESDE EMP_MASTER T1 LEFT JOIN TRANSFER T2 ON T1.employee_id=T2.employee_id WHERE NVL(T2.DATE_OF_TRANSFER,SYSDATE) =NVL((SELECT MAX(T3.DATE_OF_TRANSFER) FROM TRANSFER T3 WHERE T3.employee_id=T2 .id_empleado),SYSDATE); - TechDo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.