简体   繁体   English

仅当第一次连接没有结果时才连接表

[英]Join tables only if the first join yields no results

I have 5 tables A, B, C, D, E.我有 5 个表 A、B、C、D、E。

The primary key of A is a foreign key in B, C, D, E. They don't have their own primary key. A 的主键是 B、C、D、E 中的外键。它们没有自己的主键。

I have to implement a certain logic where我必须实现某种逻辑,其中

if ("A JOIN B JOIN C" IS NOT NULL)
    return result of "A JOIN B JOIN C"
else if ("A JOIN C" IS NOT NULL)
    return result of "A JOIN C"
else if ("A JOIN D" IS NOT NULL)
    return result of "A JOIN D"
else if ("A JOIN E" IS NOT NULL)
    return result of "A JOIN E"
else return A

where A.primarykey = <some value>

I have to implement this in a single sql and not a stored proc.我必须在单个 sql 而不是存储过程中实现它。 I can't think of a way to achieve this.我想不出实现这一目标的方法。 I use DB2.我使用 DB2。 I would really appreciate if you could give some directions on how to proceed.如果您能就如何进行提供一些指导,我将不胜感激。

You could do something like this:你可以这样做:

select
  case 
     when B.key is not null and C.key is not null then 'A+B+C'
     when C.key is not null then 'A+C'
     when D.key is not null then 'A+D'
     when E.key is not null then 'A+E'
  end
from A
left join B on B.key = A.key
left join C on C.key = A.key
left join D on D.key = A.key
left join E on E.key = A.key
left join F on F.key = A.key

The case statement will stop evaluating further as soon as a when condition is met, so effectively you've got an if-else if block.一旦满足when条件, case语句将停止进一步评估,因此有效地您有一个if-else if块。

I am just returning string values in the example, but you could return field values as well, depending on your needs, eg:我只是在示例中返回字符串值,但您也可以返回字段值,具体取决于您的需要,例如:

  case 
     when B.key is not null and C.key is not null then b.f1
     when C.key is not null then c.f1
     when D.key is not null then d.f1
     when E.key is not null then e.f1
  end as 'f1'
  ,
  case 
     when B.key is not null and C.key is not null then b.f2
     when C.key is not null then c.f2
     when D.key is not null then d.f2
     when E.key is not null then e.f2
  end as 'f2'

You want LEFT JOIN s with with some additional logic to handle the "else" part of what you are doing:您希望LEFT JOIN带有一些额外的逻辑来处理您正在做的“其他”部分:

select . . .
from A left join
     B 
     on B.key = A.key left join
     C
     on C.key = A.key left join
     C c2
     on c2.key = A.key and
        c.key is null left join  -- first attempt failed
     D
     on D.key = A.key and
        c.key is null and
        c2.key is null left join  -- earlier joins failed
     E
     on e.key = A.key and
        c.key is null and
        c2.key is null and
        d.key is null

Try the following.请尝试以下操作。 You may edit input data to check the result.您可以编辑输入数据以检查结果。

WITH 
  A (ID, AV) AS (VALUES (1, 'A1'))
, B (ID, BV) AS (VALUES 
(1, 'B1'), (1, 'B2')
--(2, 'B1'), (2, 'B2')
) , C (ID, CV) AS (VALUES 
(1, 'C1'), (1, 'C2'), (1, 'C3')
--(2, 'C1'), (2, 'C2'), (2, 'C3')
), D (ID, DV) AS (VALUES 
(1, 'D1'), (1, 'D2')
--(2, 'D1'), (2, 'D2')
) , E (ID, EV) AS (VALUES 
(1, 'E1'), (1, 'E2'), (1, 'E3')
--(2, 'E1'), (2, 'E2'), (2, 'E3')
)
SELECT A.ID, A.AV, B.BV, C.CV, C1.CV AS CV1, D.DV, E.EV
, 
CASE
  WHEN B.ID  IS NOT NULL THEN 'A+B+C'
  WHEN C1.ID IS NOT NULL THEN 'A+C'
  WHEN D.ID  IS NOT NULL THEN 'A+D'
  WHEN E.ID  IS NOT NULL THEN 'A+E'
  ELSE 'A'
END JOIN_PATH
FROM A
LEFT JOIN 
(
B 
JOIN C ON C.ID=B.ID
)              ON B.ID  = A.ID 
LEFT JOIN C C1 ON C1.ID = A.ID AND B.ID IS NULL
LEFT JOIN D    ON D.ID  = A.ID AND B.ID IS NULL AND C1.ID IS NULL 
LEFT JOIN E    ON E.ID  = A.ID AND B.ID IS NULL AND C1.ID IS NULL AND D.ID IS NULL;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM