Igo*_*nov 1 oracle plsql join left-join
我正在尝试在 Oracle 中使用 LEFT JOIN 连接两个表。我只需要包含“正确”连接表中的第一条记录。
请参阅下面的示例:
表A
code | emp_no
101 | 11111
102 | 22222
103 | 33333
104 | 44444
105 | 55555
Run Code Online (Sandbox Code Playgroud)
表B
code | city | county
101 | City1 | Country1
101 | City2 | Country1
101 | City3 | Country1
102 | City4 | Country2
103 | City5 | Country3
Run Code Online (Sandbox Code Playgroud)
预期输出:
code | emp_no | city | county
101 | 11111 | City1 | Country1
102 | 22222 | City4 | Country2
103 | 33333 | City5 | Country3
104 | 44444 | NULL | NULL
105 | 55555 | NULL | NULL
Run Code Online (Sandbox Code Playgroud)
我需要从表 B 中选择第一个匹配的记录并忽略所有其他行。
上面的查询假设有效:
SELECT *
FROM TABLE_A a
LEFT JOIN TABLE_B b ON b.CODE = a.CODE
AND b.CODE =
(
SELECT CODE
FROM TABLE_B
WHERE ROWNUM = 1
)
Run Code Online (Sandbox Code Playgroud)
但我收到错误:ORA-01799: 列可能未外部连接到子查询
我怎样才能做到这一点?
谢谢
在 Oracle 12c 上,您可以使用OUTER APPLYandFETCH FIRST子句:
SELECT *
FROM tableA a
OUTER APPLY (
SELECT * FROM tableB b
WHERE a.code = b.code
ORDER BY city, county
FETCH FIRST ROW ONLY
)
CODE EMP_NO CODE CITY COUNTY
---------- ---------- ---------- ----- --------
101 11111 101 City1 Country1
102 22222 102 City4 Country2
103 33333 103 City5 Country3
104 44444
105 55555
Run Code Online (Sandbox Code Playgroud)
您可以使用min()aggrenate函数的keep (dense_rank first ...)语法来从外连接表“第一个”匹配的数据:
select a.code, a.emp_no,
min(b.city) keep (dense_rank first order by city, county) as city,
min(b.county) keep (dense_rank first order by city, county) as county
from table_a a
left join table_b b on b.code = a.code
group by a.code, a.emp_no
order by a.code, a.emp_no;
CODE EMP_NO CITY COUNTY
---------- ---------- ----- --------
101 11111 City1 Country1
102 22222 City4 Country2
103 33333 City5 Country3
104 44444
105 55555
Run Code Online (Sandbox Code Playgroud)
不过,您必须定义“第一”的含义 - 我已经city, county在 keep 子句中使用 order by ,但是您可能还有另一列您没有显示应该指示顺序。
(您可以按 null 排序以使其有点随意,但这通常不是一个好主意,尤其是因为稍后运行相同的查询可能会为相同的数据提供不同的结果。)