出于问题的目的,此示例是发明的。
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)
假设COUNTRY_ID
不是Country表中的主键,而Country表上的上述连接可能返回多行。我们不知道有多少行,我们不关心为什么有多行。我们只想加入其中一个,所以我们每个省都会得到一行。
我为连接尝试了子查询,但无法通过PR.COUNTRY_ID
传递给Oracle 11.2。还有其他方法可以实现这一目标吗?
答案 0 :(得分:0)
如果您有Oracle 12c,则可以在联接中使用LATERAL
视图。像这样:
SELECT
PR.PROVINCE_NAME
,CO.COUNTRY_NAME
FROM
PROVINCE PR
CROSS JOIN LATERAL (
SELECT * FROM COUNTRY CO
WHERE CO.COUNTRY_ID=PR.COUNTRY_ID
FETCH FIRST 1 ROWS ONLY) CO
WHERE
PR.PROVINCE_ID IN (1,2)
在Oracle 11.2中,您可以使用这些内容。根据{{1}}的大小以及每COUNTRY
个重复的数量,它可以比12c方法表现更好或更好。 (缓冲区越少,但需要更多内存)。
COUNTRY_ID
答案 1 :(得分:0)
处理没有PK的表的典型安全方法是使用唯一索引(重复行的row_numer)扩展重复列
在你的情况下,这将是:
with COUNTRY_UNIQUE as (
select COUNTRY_ID,
row_number() over (partition by COUNTRY_ID order by COUNTRY_NAME) rn,
COUNTRY_NAME
from country)
select * from COUNTRY_UNIQUE
order by COUNTRY_ID, rn;
导致
COUNTRY_ID RN COUNTRY_NAME
---------- ---------- ------------
1 1 C1
2 1 C2
2 2 C3
COUNTRY_ID
和RN
的组合是唯一的,因此如果仅约束RN = 1
,则COUNTRY_ID
是唯一的。
您可以定义重复记录的顺序并用它来控制选择 - 在我们的例子中,我们选择最小的COUNTRY_NAME。
整个联接使用此子查询并限制RN = 1
with COUNTRY_UNIQUE as (
select COUNTRY_ID,
row_number() over (partition by COUNTRY_ID order by COUNTRY_NAME) rn,
COUNTRY_NAME
from country)
SELECT
PR.PROVINCE_NAME
,CO.COUNTRY_NAME
FROM
PROVINCE PR
JOIN COUNTRY_UNIQUE CO ON CO.COUNTRY_ID=PR.COUNTRY_ID
WHERE
PR.PROVINCE_ID IN (1,2)
AND CO.RN = 1; /* consider only unique countries */