Sql 如何在联接中引用联接中的字段?

Sql 如何在联接中引用联接中的字段?,sql,join,inner-join,Sql,Join,Inner Join,在JOIN语句中选择子查询中的特定字段时,可以使用点表示法引用table.field\u名称,但是,在第一个联接中使用另一个子查询联接时,该怎么办 我的加入示例w/in-JOIN: JOIN (SELECT BUDGET.protocol_id, BUDGET.completed_date, CONTRACT.completed_date, REQUEST.completed_date, RECEIVE.completed_date, PC.completed_date, FC.complet

在JOIN语句中选择子查询中的特定字段时,可以使用点表示法引用table.field\u名称,但是,在第一个联接中使用另一个子查询联接时,该怎么办

我的加入示例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

我一直在尝试使用子查询来选择特定的任务完成日期,因此在select语句中,我的直觉是为每个任务使用task.BUDGET.completed_date。然而,我得到了一个定义模糊的ORA-00918:column,因此使用completed_date似乎所有内容都有问题使用条件聚合:

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;

我不太确定任务列表id是否适合。您可能还希望通过该方法进行聚合。

如果需要在子查询中访问子查询的列,则只需在中间子查询的选择中使用它们:

 SELECT middle_subquery.c1
 FROM 
 (
    SELECT inner_subquery.c1
    FROM
    (
       SELECT count(*) c1 FROM tab
    ) inner_subquery
 ) middle_subquery
而不是

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

我花了一点时间才明白,但我想我明白了

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
因此,“预算完成日期”现在可以称为“任务完成日期”。pc完成日期和经理完成日期等也可以。这是它的混淆。只是别名:

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

这将使每个task.complete_日期保持唯一,您可以从中将它们称为task.budget_completed_日期。有意义吗?

如果你运行你发布的所有代码,减去开始它的连接,它会运行吗?我觉得这很好,所以我猜你的错误是在外部选择或分组上。子查询本身肯定会运行,尽管运行速度很慢。当在主查询中选择我添加的语句时,会出现问题:“TASK.BUDGET.completed_date,TASK.CONTRACT.completed_date,TASK.REQUEST.completed_date,TASK.RECEIVE.completed_date,TASK.PC.completed_date,TASK.FC.completed_date,TASK.MGR.completed_date'在PCL.protocol_id=TASK.BUDGET.protocol_id上抛出00918错误任务-指向该任务的开放括号在哪里?每个子查询最好被认为是它自己的表…其中的所有内容都是自包含的,不能引用它之外的任何对象。task.budget.completed_日期永远不会正确引用。编辑:如果您没有该任务引用,则此操作有效,不是吗?您需要为每个子查询中的列设置别名以避免混淆选择completed_date作为budget_completed_date或类似的名称正确的别名应该是TASK。completed_date。。。预算的内部别名将不会传递到外部查询。只有子查询/派生表别名将执行此任务。同样,为每个完成的_date列指定自己的别名。即。。CONTRACT.completed\u date作为ContractCompletedDate,然后从外部查询中的该列名称中选择它们。即。。TASK.contractedcompleteddate谢谢@Gordon Linoff。我是新手,所以不熟悉条件聚合。你有什么推荐信可以让我学到更多吗?我想我会使用别名快速修复,即使它比较慢,然后了解更多关于条件聚合的信息optimize@Dan . . . 这似乎是代码的一个主要简化,一个聚合查询而不是大量的连接。没错,将其放入更大的查询中效果更好。谢谢,你明白了。别名是个问题。仍然是一个非常缓慢的操作,但我将在稍后进行优化。谢谢你看看Gordon关于速度改进的回答…你在这里几乎做了7次全表扫描,而这可以更有效地完成。您在这里所做的工作也可以被视为“数据透视”或“交叉制表”,这取决于您使用的是哪种数据库,有更有效的方法使用它。