2016-10-13 43 views
0

我正在使用子查询进行连接操作。当我硬编码参数,事情工作正常。但是这些参数必须来自我认为被称为相关查询的外部sql。我想通过它们使用表别名,但这会导致invalid identifier如何在Oracle相关子查询连接中使用别名?

发明的问题的目的:

SELECT 
    PR.PROVINCE_NAME 
    ,CO.COUNTRY_NAME 
FROM 
    PROVINCE PR 
    JOIN (
     SELECT COUNTRY_ID, COUNTRY_NAME 
     FROM COUNTRY 
     WHERE COUNTRY_ID=PR.COUNTRY_ID 
    ) CO ON CO.COUNTRY_ID=PR.COUNTRY_ID 
WHERE 
    PR.PROVINCE_ID IN (1,2) 

这是键入的,所以我希望我没有出台任何语法问题在这里。该问题具体是关于WHERE条款后面的COUNTRY_ID=PR.COUNTRY_ID。这些子查询中别名是否合法?

+0

好,只要我更换'WHERE COUNTRY_ID = PR.COUNTRY_ID'与'WHERE COUNTRY_ID = 123',事情工作正常。它可能与通过Oracle SQL Developer Version 3.2.09运行此查询有关吗? – user6651485

回答

0

您在两个不同位置使用别名。对于一个它是合法的,对于其它不是:

SELECT pr.province_name, co.country_name 
FROM province pr 
    JOIN (
    SELECT country_id, country_name 
    FROM country 
    WHERE country_id = pr.country_id --<< this reference to the outer table/alias is invalid 
) co ON co.country_id = pr.country_id -- this is valid 
WHERE pr.province_id IN (1,2) 

随着(标准)加入到派生表中,选择不能从外部选择访问的别名或表。您得到的“无效标识符”是由行WHERE country_id = pr.country_id引起的。

鉴于您的JOIN条件,您可以安全地将其删除而不更改结果。 Oracle优化器足够聪明,可以将该条件推送到派生表中。

事实上优化器将重写查询到:

SELECT pr.province_name, co.country_name 
FROM province pr 
    JOIN country co ON co.country_id = pr.country_id 
WHERE pr.province_id IN (1,2); 

然而有从在派生表外部查询访问表(或别名)的一种方法:它被称为一个横向加入。

这是SQL标准的一部分,但你需要甲骨文12,以便能够使用它:

以下法律:

SELECT pr.province_name,co.country_name 
FROM province pr 
    JOIN LATERAL (
     SELECT country_id, country_name 
     FROM country 
     WHERE country_id = pr.country_id 
    ) co ON co.country_id = pr.country_id 
WHERE pr.province_id IN (1,2)
+0

好的。那么这很简单。我正在使用版本11.2,不接受LATERAL。另外,我为了这个问题发明了我的例子,并且不能像你所建议的那样重写我的查询。原因是我在该连接中获得多行,并且suquery将帮助我减少到我需要的单行。感谢您的及时回应。 – user6651485