Al seleccionar un campo específico dentro de una subconsulta en una instrucción JOIN, utiliza la notación de puntos para hacer referencia a la tabla.nombre_campo, sin embargo, ¿qué hacer cuando se usa otra subconsulta JOIN dentro de esa primera UNIÓN?

Mi ejemplo de JOIN w / in JOIN:

JOIN (SELECT 
BUDGET.protocol_id, BUDGET.completed_date,
CONTRACT.completed_date,
REQUEST.completed_date,
RECEIVE.completed_date,
PC.completed_date,
FC.completed_date,
MGR.completed_date

FROM (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Budget%') BUDGET 

JOIN (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Contract%') CONTRACT 
    ON BUDGET.protocol_id = CONTRACT.protocol_id
    AND BUDGET.task_list_id = CONTRACT.task_list_id

JOIN (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Request%') REQUEST 
    ON BUDGET.protocol_id = REQUEST.protocol_id
    AND BUDGET.task_list_id = REQUEST.task_list_id

JOIN (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Protocol%') PC 
    ON BUDGET.protocol_id = PC.protocol_id
    AND BUDGET.task_list_id = PC.task_list_id

JOIN (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Financials%') FC 
    ON BUDGET.protocol_id = FC.protocol_id
    AND BUDGET.task_list_id = FC.task_list_id

JOIN (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Manager%') MGR 
    ON BUDGET.protocol_id = MGR.protocol_id
    AND BUDGET.task_list_id = MGR.task_list_id  

JOIN (SELECT completed_date, task_list_id, protocol_id FROM task WHERE task_name LIKE 'Receive%') RECEIVE
    ON BUDGET.protocol_id = RECEIVE.protocol_id
    AND BUDGET.task_list_id = RECEIVE.task_list_id
) TASK ON PCL.protocol_id = TASK.BUDGET.protocol_id

Lo que he estado tratando de hacer con las subconsultas es seleccionar las fechas de finalización de la tarea específica, por lo que en la instrucción SELECT mi instinto es usar TASK.BUDGET.completed_date, para cada tarea. Sin embargo, obtengo un ORA-00918: columna ambiguamente definida, por lo que parece que hay algo mal con todo usando complete_date

2
Dan 18 oct. 2017 a las 21:55

3 respuestas

La mejor respuesta

Usar agregación condicional:

SELECT t.protocol_id,
       MAX(CASE WHEN task_name LIKE 'Budget%' THEN completed_date END) as budget_completed_date,
         . . . 
FROM task t
GROUP BY protocol_id;

No estoy muy seguro de cómo encaja task_list_id. También es posible que desee agregarse por eso.

2
Gordon Linoff 18 oct. 2017 a las 19:05

Me costó un poco entenderlo, pero creo que te tengo.

SELECT 
BUDGET.protocol_id, 
BUDGET.completed_date,
CONTRACT.completed_date,
REQUEST.completed_date,
RECEIVE.completed_date,
PC.completed_date,
FC.completed_date,
MGR.completed_date
...
)task

Por lo tanto, 'budget.completed_date' ahora se puede denominar como 'task.completed_date'. Y también puede pc.completed_date y mgr.completed_date, etc. Esa es su confusión. Solo alias:

SELECT 
BUDGET.protocol_id  as budget_protocol_id
BUDGET.completed_date as budget_completed_date,
    SELECT 
BUDGET.protocol_id, BUDGET.completed_date,
CONTRACT.completed_date as contract_completed_date,
REQUEST.completed_date as request_completed_date,
RECEIVE.completed_date as receive_completed_date,
etc
...
)task

Esto mantendrá cada task.complete_date único y puede referirse a ellos desde allí como task.budget_completed_date. ¿Tener sentido?

1
Twelfth 18 oct. 2017 a las 19:37

Si necesita acceder a columnas de subconsulta en subconsulta, simplemente úselas en SELECT de la subconsulta intermedia:

 SELECT middle_subquery.c1
 FROM 
 (
    SELECT inner_subquery.c1
    FROM
    (
       SELECT count(*) c1 FROM tab
    ) inner_subquery
 ) middle_subquery

En lugar de

 SELECT middle_subquery.inner_subquery.c1
 FROM 
 (
    SELECT *
    FROM
    (
       SELECT count(*) c1 FROM tab
    ) inner_subquery
 ) middle_subquery
0
Radim Bača 18 oct. 2017 a las 19:05