如何在Oracle相关子查询连接中使用别名?

时间:2016-10-13 14:06:27

标签: oracle correlated-subquery

我使用子查询进行连接操作。当我硬编码参数时,事情很好。但那些参数必须来自外部sql,我认为这被称为相关查询。我想使用表别名传递它们,但这导致invalid identifier

示例发明了以用于提问:

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)

这是输入的,所以我希望我在这里没有介绍任何语法问题。问题是关于COUNTRY_ID=PR.COUNTRY_ID条款之后的WHERE。这些子查询中的别名是否合法?

1 个答案:

答案 0 :(得分:2)

您在两个不同的位置使用别名。一方面它是合法的,另一方面则不合法:

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标准的一部分,但您需要Oracle 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)