LEFT JOIN 之后的 ORACLE JOIN
ORACLE JOIN after LEFT JOIN
我有四个 table,其中三个通过 LEFT JOIN 连接到主文件。
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA ON TCSRMA.CAASTYP = 'R' AND TCSRMA.CADOCO = ZADOCO
LEFT JOIN PRODDTA.F40051 TRMAOS ON (TCSRMA.CAKCOO = TRMAOS.RDRKCO AND TCSRMA.CARORN = TRMAOS.RDRORN AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
LEFT JOIN PRODDTA.F4311 ON (TRMAOS.RDOKCO = PDKCOO AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO AND TRMAOS.RDOCTO = PDDCTO AND TRMAOS.RDPOLN = PDLNID AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
这个查询可能会给我带来重复项,因为它们都是 LEFT。
如何限制结果,使 table F40051 取决于 F4311(即,如果 F4311 (PD) 不存在,它不会显示 F40051 (RD)),但仍显示值 1672095?如果我将 INNER JOIN 应用于 F4311...
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA ON TCSRMA.CAASTYP = 'R' AND TCSRMA.CADOCO = ZADOCO
LEFT JOIN PRODDTA.F40051 TRMAOS ON (TCSRMA.CAKCOO = TRMAOS.RDRKCO AND TCSRMA.CARORN = TRMAOS.RDRORN AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
JOIN PRODDTA.F4311 ON (TRMAOS.RDOKCO = PDKCOO AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO AND TRMAOS.RDOCTO = PDDCTO AND TRMAOS.RDPOLN = PDLNID AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
...我会失去一条记录
添加子查询可能会影响我的性能,因为没有直接的 link,但是 SQL 需要 运行 中的整个 SELECT首先是子查询,这会使它变得非常慢。
有什么想法吗?
我偶然发现了一个解决方案:
Using left join and inner join in the same query
参考 Gajus 的回答。
基本上我们可以玩括号:
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA ON TCSRMA.CAASTYP = 'R' AND TCSRMA.CADOCO = ZADOCO
LEFT JOIN (PRODDTA.F40051 TRMAOS
JOIN PRODDTA.F4311 ON TRMAOS.RDOKCO = PDKCOO AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO AND TRMAOS.RDOCTO = PDDCTO AND TRMAOS.RDPOLN = PDLNID AND (PDLTTR, PDNXTR) NOT IN (('980', '999'))
LEFT JOIN PRODDTA.F43121 ON PRMATC = '1' AND PDKCOO = PRKCOO AND PDDOCO = PRDOCO AND PDDCTO = PRDCTO AND PDLNID = PRLNID)
ON TCSRMA.CAKCOO = TRMAOS.RDRKCO AND TCSRMA.CARORN = TRMAOS.RDRORN AND TCSRMA.CADCTO = TRMAOS.RDRCTO
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
结果:
在 sub-query:
中执行连接
SELECT ZADOCO,
CADOCO,
RDRORN,
RDOORN,
PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA
ON ( TCSRMA.CAASTYP = 'R'
AND TCSRMA.CADOCO = ZADOCO)
LEFT JOIN (
SELECT * -- Name the columns you want.
FROM PRODDTA.F40051 TRMAOS
JOIN PRODDTA.F4311
ON ( TRMAOS.RDOKCO = PDKCOO
AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO
AND TRMAOS.RDOCTO = PDDCTO
AND TRMAOS.RDPOLN = PDLNID
AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
)
ON ( TCSRMA.CAKCOO = TRMAOS.RDRKCO
AND TCSRMA.CARORN = TRMAOS.RDRORN
AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
WHERE ZASTAW = '2'
AND ZADOCO IN (172755, 1672095, 1675619)
或者 INNER JOIN
然后 RIGHT OUTER JOIN
:
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F4311
INNER JOIN PRODDTA.F40051 TRMAOS
ON ( TRMAOS.RDOKCO = PDKCOO
AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO
AND TRMAOS.RDOCTO = PDDCTO
AND TRMAOS.RDPOLN = PDLNID
AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
RIGHT OUTER JOIN PRODDTA.F90CG503 TCSRMA
ON ( TCSRMA.CAKCOO = TRMAOS.RDRKCO
AND TCSRMA.CARORN = TRMAOS.RDRORN
AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
RIGHT OUTER JOIN PRODDTA.F1755 T2
ON ( TCSRMA.CAASTYP = 'R'
AND TCSRMA.CADOCO = ZADOCO)
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
db<>fiddle here
我有四个 table,其中三个通过 LEFT JOIN 连接到主文件。
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA ON TCSRMA.CAASTYP = 'R' AND TCSRMA.CADOCO = ZADOCO
LEFT JOIN PRODDTA.F40051 TRMAOS ON (TCSRMA.CAKCOO = TRMAOS.RDRKCO AND TCSRMA.CARORN = TRMAOS.RDRORN AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
LEFT JOIN PRODDTA.F4311 ON (TRMAOS.RDOKCO = PDKCOO AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO AND TRMAOS.RDOCTO = PDDCTO AND TRMAOS.RDPOLN = PDLNID AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
这个查询可能会给我带来重复项,因为它们都是 LEFT。
如何限制结果,使 table F40051 取决于 F4311(即,如果 F4311 (PD) 不存在,它不会显示 F40051 (RD)),但仍显示值 1672095?如果我将 INNER JOIN 应用于 F4311...
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA ON TCSRMA.CAASTYP = 'R' AND TCSRMA.CADOCO = ZADOCO
LEFT JOIN PRODDTA.F40051 TRMAOS ON (TCSRMA.CAKCOO = TRMAOS.RDRKCO AND TCSRMA.CARORN = TRMAOS.RDRORN AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
JOIN PRODDTA.F4311 ON (TRMAOS.RDOKCO = PDKCOO AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO AND TRMAOS.RDOCTO = PDDCTO AND TRMAOS.RDPOLN = PDLNID AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
...我会失去一条记录
添加子查询可能会影响我的性能,因为没有直接的 link,但是 SQL 需要 运行 中的整个 SELECT首先是子查询,这会使它变得非常慢。
有什么想法吗?
我偶然发现了一个解决方案:
Using left join and inner join in the same query
参考 Gajus 的回答。
基本上我们可以玩括号:
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA ON TCSRMA.CAASTYP = 'R' AND TCSRMA.CADOCO = ZADOCO
LEFT JOIN (PRODDTA.F40051 TRMAOS
JOIN PRODDTA.F4311 ON TRMAOS.RDOKCO = PDKCOO AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO AND TRMAOS.RDOCTO = PDDCTO AND TRMAOS.RDPOLN = PDLNID AND (PDLTTR, PDNXTR) NOT IN (('980', '999'))
LEFT JOIN PRODDTA.F43121 ON PRMATC = '1' AND PDKCOO = PRKCOO AND PDDOCO = PRDOCO AND PDDCTO = PRDCTO AND PDLNID = PRLNID)
ON TCSRMA.CAKCOO = TRMAOS.RDRKCO AND TCSRMA.CARORN = TRMAOS.RDRORN AND TCSRMA.CADCTO = TRMAOS.RDRCTO
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
结果:
在 sub-query:
中执行连接SELECT ZADOCO,
CADOCO,
RDRORN,
RDOORN,
PDDOCO
FROM PRODDTA.F1755 T2
LEFT JOIN PRODDTA.F90CG503 TCSRMA
ON ( TCSRMA.CAASTYP = 'R'
AND TCSRMA.CADOCO = ZADOCO)
LEFT JOIN (
SELECT * -- Name the columns you want.
FROM PRODDTA.F40051 TRMAOS
JOIN PRODDTA.F4311
ON ( TRMAOS.RDOKCO = PDKCOO
AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO
AND TRMAOS.RDOCTO = PDDCTO
AND TRMAOS.RDPOLN = PDLNID
AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
)
ON ( TCSRMA.CAKCOO = TRMAOS.RDRKCO
AND TCSRMA.CARORN = TRMAOS.RDRORN
AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
WHERE ZASTAW = '2'
AND ZADOCO IN (172755, 1672095, 1675619)
或者 INNER JOIN
然后 RIGHT OUTER JOIN
:
SELECT ZADOCO, CADOCO, RDRORN, RDOORN, PDDOCO
FROM PRODDTA.F4311
INNER JOIN PRODDTA.F40051 TRMAOS
ON ( TRMAOS.RDOKCO = PDKCOO
AND TO_NUMBER(TRIM(TRMAOS.RDOORN)) = PDDOCO
AND TRMAOS.RDOCTO = PDDCTO
AND TRMAOS.RDPOLN = PDLNID
AND (PDLTTR, PDNXTR) NOT IN (('980', '999')))
RIGHT OUTER JOIN PRODDTA.F90CG503 TCSRMA
ON ( TCSRMA.CAKCOO = TRMAOS.RDRKCO
AND TCSRMA.CARORN = TRMAOS.RDRORN
AND TCSRMA.CADCTO = TRMAOS.RDRCTO)
RIGHT OUTER JOIN PRODDTA.F1755 T2
ON ( TCSRMA.CAASTYP = 'R'
AND TCSRMA.CADOCO = ZADOCO)
WHERE ZASTAW = '2' AND ZADOCO IN (172755, 1672095, 1675619)
db<>fiddle here