子查询中的列外部连接 (ORA-01799)
Column outer joined in subquery (ORA-01799)
甲骨文 11g R2:
Table:
CREATE TABLE TABLE_1
(REC_ID NUMBER(10,0) NOT NULL,
REV_ID NUMBER(10,0) NOT NULL ENABLE
);
INSERT ALL
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (1,23)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (1,36)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (1,52)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (2,19)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (2,67)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (2,98)
SELECT * FROM dual;
CREATE TABLE TABLE_2
(REC_ID NUMBER(20,0) NOT NULL ENABLE
);
INSERT ALL
INTO TABLE_2 (REC_ID)
VALUES (1)
INTO TABLE_2 (REC_ID)
VALUES (2)
SELECT * FROM dual;
我想加入 Table 2 和 Table 1 但只有 Table 1 REV_ID 是某个 [=33] 的最小值 REV_ID =].
+--------+--------+--------+
| REC_ID | REC_ID | REV_ID |
+--------+--------+--------+
| 1 | 1 | 23 |
| 2 | 2 | 19 |
+--------+--------+--------+
这个Select:
SELECT * from TABLE_2 T2
LEFT OUTER JOIN TABLE_1 T1 on T1.REC_ID = T2.REC_ID
and T1.REV_ID = (SELECT MIN(REV_ID) from T1 where T1.REC_ID = T2.REC_ID)
适用于 MSSQL Server 2017 但会引发错误:
ORA-01799: a column may not be outer-joined to a subquery
在甲骨文中。
SQL Fiddle: LINK
问题:
我如何重写查询以便连接在所有 oracle 版本中都有效?
您可以尝试以下查询 -
SELECT *
from TABLE_2 T2
LEFT OUTER JOIN (SELECT REC_ID, MIN(REV_ID)
FROM TABLE_1
GROUP BY REC_ID) T1 on T1.REC_ID = T2.REC_ID;
您可以将 CTE 与 row_number
一起使用,以 分类 具有最小 REV_ID
的行,并且仅对这些行进行外部连接。
优点是即使您想要 T1
中的一些其他属性,这种方法也能奏效
with t1_min as
(select REC_ID, REV_ID,
row_number() over (partition by REC_ID order by REV_ID) as rn
from TABLE_1)
SELECT t2.rec_id t2_rec_id,t1.rec_id t1_rec_id,
t1.rev_id
from TABLE_2 T2
LEFT OUTER JOIN t1_min T1 on T1.REC_ID = T2.REC_ID
and t1.rn = 1
T2_REC_ID T1_REC_ID REV_ID
---------- ---------- ----------
1 1 23
2 2 19
甲骨文 11g R2:
Table:
CREATE TABLE TABLE_1
(REC_ID NUMBER(10,0) NOT NULL,
REV_ID NUMBER(10,0) NOT NULL ENABLE
);
INSERT ALL
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (1,23)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (1,36)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (1,52)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (2,19)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (2,67)
INTO TABLE_1 (REC_ID,REV_ID)
VALUES (2,98)
SELECT * FROM dual;
CREATE TABLE TABLE_2
(REC_ID NUMBER(20,0) NOT NULL ENABLE
);
INSERT ALL
INTO TABLE_2 (REC_ID)
VALUES (1)
INTO TABLE_2 (REC_ID)
VALUES (2)
SELECT * FROM dual;
我想加入 Table 2 和 Table 1 但只有 Table 1 REV_ID 是某个 [=33] 的最小值 REV_ID =].
+--------+--------+--------+
| REC_ID | REC_ID | REV_ID |
+--------+--------+--------+
| 1 | 1 | 23 |
| 2 | 2 | 19 |
+--------+--------+--------+
这个Select:
SELECT * from TABLE_2 T2
LEFT OUTER JOIN TABLE_1 T1 on T1.REC_ID = T2.REC_ID
and T1.REV_ID = (SELECT MIN(REV_ID) from T1 where T1.REC_ID = T2.REC_ID)
适用于 MSSQL Server 2017 但会引发错误:
ORA-01799: a column may not be outer-joined to a subquery
在甲骨文中。
SQL Fiddle: LINK
问题: 我如何重写查询以便连接在所有 oracle 版本中都有效?
您可以尝试以下查询 -
SELECT *
from TABLE_2 T2
LEFT OUTER JOIN (SELECT REC_ID, MIN(REV_ID)
FROM TABLE_1
GROUP BY REC_ID) T1 on T1.REC_ID = T2.REC_ID;
您可以将 CTE 与 row_number
一起使用,以 分类 具有最小 REV_ID
的行,并且仅对这些行进行外部连接。
优点是即使您想要 T1
with t1_min as
(select REC_ID, REV_ID,
row_number() over (partition by REC_ID order by REV_ID) as rn
from TABLE_1)
SELECT t2.rec_id t2_rec_id,t1.rec_id t1_rec_id,
t1.rev_id
from TABLE_2 T2
LEFT OUTER JOIN t1_min T1 on T1.REC_ID = T2.REC_ID
and t1.rn = 1
T2_REC_ID T1_REC_ID REV_ID
---------- ---------- ----------
1 1 23
2 2 19