如果存在匹配值,则从另一个 table 检索数据 - 否则 return 基于第一个连接条件

Retrieve data from another table if there is a matching value - else return based on first join condition

我试图通过将两个 table 加入主列来获取数据。但是,如果右侧的第二列和第三列可用 table,则考虑它们和 return 其对应的列。

LEFT_TAB
USER  PRIMARY  SECONDARY  TERTIARY
1       A1       B1        (null)
2       X1     (null)      (null)

RIGHT_TAB
PRIMARY SECONDARY TERTIARY INDICATOR
  A1       B1      (null)    I1
  A1     (null)    (null)    I2
  X1     (null)    (null)    I3

Expected Output:
USER  PRIMARY  SECONDARY  TERTIARY INDICATOR
  1     A1         B1      (null)    I1
  2     X1       (null)    (null)    I3

我已经在 PRIMARY 上尝试过 INNER JOIN,因为这是主列,而 SECONDARY 和 TERTIARY 是可选的。如果它们可用,那么我们将使用它们和相应的行(LEFT OUTER JOIN),但它 return 是重复的。

select lft.user_id,lft.primary,lft.secondary,lft.tertiary,rit.indication
from left_tab lft
INNER JOIN right_tab rit ON left.primary = rit.primary
LEFT JOIN right_tab rite ON
(left.secondary = rite.secondary OR left.tertiary = rite.tertiary) ---(join that's bringing dups)
;

OUTPUT:
USER  PRIMARY  SECONDARY  TERTIARY INDICATOR
  1     A1         B1      (null)    I1
  1     A1         B1      (null)    I2 --duplicate
  2     X1       (null)    (null)    I3

从 Oracle 12 开始,您可以使用:

SELECT l.user_id,
       l.primary,
       l.secondary,
       l.tertiary,
       r.indicator
from   left_tab l
       CROSS JOIN LATERAL (
         SELECT r.*
         FROM   right_tab r
         WHERE  l.primary = r.primary
         AND    (l.secondary = r.secondary OR r.secondary IS NULL)
         AND    (l.tertiary = r.tertiary OR r.tertiary IS NULL)
         ORDER BY (CASE WHEN r.secondary IS NOT NULL THEN 1 ELSE 0 END
                  + CASE WHEN r.tertiary  IS NOT NULL THEN 1 ELSE 0 END) DESC
         FETCH FIRST ROW ONLY
       ) r;

其中,对于示例数据:

CREATE TABLE LEFT_TAB (USER_ID, PRIMARY, SECONDARY, TERTIARY) AS
SELECT 1, 'A1', 'B1', CAST(null AS VARCHAR2(2)) FROM DUAL UNION ALL
SELECT 2, 'X1', null, null FROM DUAL UNION ALL
SELECT 3, 'Y1', 'Y2', 'Y3' FROM DUAL;

CREATE TABLE RIGHT_TAB (PRIMARY, SECONDARY, TERTIARY, INDICATOR) AS
SELECT 'A1', 'B1', CAST(null AS VARCHAR2(2)), 'I1' FROM DUAL UNION ALL
SELECT 'A1', null, null, 'I2' FROM DUAL UNION ALL
SELECT 'X1', null, null, 'I3' FROM DUAL UNION ALL
SELECT 'Y1', null, 'Y3', 'I4' FROM DUAL UNION ALL
SELECT 'Y1', 'Y2', 'Y3', 'I5' FROM DUAL UNION ALL
SELECT 'Y1', 'Y2', null, 'I6' FROM DUAL;

输出:

USER_ID PRIMARY SECONDARY TERTIARY INDICATOR
1 A1 B1 I1
2 X1 I3
3 Y1 Y2 Y3 I5

db<>fiddle here