我正在使用连接操作的子查询。当我硬编码参数时,一切正常。但是这些参数必须来自外部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)
这是键入的,所以我希望这里没有引入任何语法问题。这个问题是关于WHERE
条款之后的COUNTRY_ID=PR.COUNTRY_ID
的。在这样的子查询中别名合法吗?
您在两个不同的位置使用别名。一个是合法的,另一个是不合法的:
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)