如何将主查询列值传递给嵌套子查询的条件?

时间:2019-05-07 08:57:17

标签: c#-4.0 oracle11g oracle10g

我正在使用嵌套子查询编写此查询,以根据PREPARED_BY表中的VERIFIED_BY查找AUTHORIZED_BYCONDATEExpenditure,但是在我的子查询中Expenditure表对象CONDATE无法识别,并引发此错误:

  

ORA-00904:“ EX”。“ CONDATE”:无效的标识符。

代码:

SELECT ex.conno,
       ex.itemno,
       ex.adv_no || ' ' || to_char(ex.condate, 'DD-MON-YYYY') chequenodate,
       ex.conname,
       ex.apaid,
       ex.dpayment,
       gf.gf_name,
       expenditure_type,
       ex.off_code,
       ofc.officename,
       ex.remarks,
       (SELECT prepared_by
        FROM   (SELECT prepared_by
                FROM   authorization
                WHERE  (pre_last_date >= ex.condate OR pre_last_date IS NULL)
                AND    project_id = 128
                ORDER  BY id ASC)
        WHERE  rownum = 1) AS prepared_by,
       (SELECT verified_by
        FROM   (SELECT verified_by
                FROM   authorization
                WHERE  (ve_last_date >= ex.condate OR ve_last_date IS NULL)
                AND    project_id = 128
                ORDER  BY id ASC)
        WHERE  rownum = 1) AS verified_by,
       (SELECT authorized_by
        FROM   (SELECT authorized_by
                FROM   authorization
                WHERE  (au_last_date >= ex.condate OR au_last_date IS NULL)
                AND    project_id = 128
                ORDER  BY id ASC)
        WHERE  rownum = 1) AS authorized_by

FROM   expenditure ex
INNER  JOIN officecode ofc
ON     ofc.off_code = ex.off_code
INNER  JOIN coa_category ca
ON     ca.coa_cat_id = ex.coa_cat_id
INNER  JOIN g_fund_type gf
ON     gf.gf_type_id = ca.gf_type_id
WHERE  ex.conno = 'MGSP/PMU/NON/145'
AND    ex.itemno = 149;

1 个答案:

答案 0 :(得分:1)

您遇到的问题是父表只能由下一级的子查询引用。您正在尝试从子查询向下两层访问父表中的列,因此为什么会出现错误。

为了访问子查询中的父列,您将需要重写它,使其仅向下一层。

这可以通过使用KEEP FIRST/LAST聚合函数来实现,例如:

SELECT ex.conno,
       ex.itemno,
       ex.adv_no || ' ' || to_char(ex.condate, 'DD-MON-YYYY') chequenodate,
       ex.conname,
       ex.apaid,
       ex.dpayment,
       gf.gf_name,
       expenditure_type,
       ex.off_code,
       ofc.officename,
       ex.remarks,
       (SELECT MAX(a.prepared_by) KEEP (dense_rank FIRST ORDER BY a.id ASC)
        FROM   authorizatiion a
        WHERE  (a.pre_last_date >= ex.condate OR a.pre_last_date IS NULL)
        AND     a.project_id = 128) prepared_by,
       (SELECT MAX(a.verified_by) KEEP (dense_rank FIRST ORDER BY a.id ASC)
        FROM   authorizatiion a
        WHERE  (a.ve_last_date >= ex.condate OR a.ve_last_date IS NULL)
        AND     a.project_id = 128) verified_by,
       (SELECT MAX(a.authorized_by) KEEP (dense_rank FIRST ORDER BY a.id ASC)
        FROM   authorizatiion a
        WHERE  (a.au_last_date >= ex.condate OR a.au_last_date IS NULL)
        AND     a.project_id = 128) authorized_by
FROM   expenditure ex
       INNER JOIN officecode ofc ON ofc.off_code = ex.off_code
       INNER JOIN coa_category ca ON ca.coa_cat_id = ex.coa_cat_id
       INNER JOIN g_fund_type gf ON gf.gf_type_id = ca.gf_type_id
WHERE  ex.conno = 'MGSP/PMU/NON/145'
AND    ex.itemno = 149;

我在这里使用过MAXFIRST;这意味着,如果有多个具有相同最低ID的行,则将使用prepare_by列的最大值。如果您想要最低的值,可以将其更改为MIN。仅当每个id的行多于此时才相关,否则,它仅返回最低id的prepare_by列的值。