【问题标题】:How to left outer join from two tables to a third table如何将两个表的外连接左连接到第三个表
【发布时间】:2013-02-28 16:43:15
【问题描述】:

我有三个表 A B 和 C (最后一个是我想要的结果)

A.id        B.age         C.id C.age      result id  age
   1            5            1     5              1    5
   2            6            2     0           null null
   3            7            0     7           null null
   4            8            4     8              4    8
   5            9            5     9              5    9

我想做一个从 A 和 B 到 C 的外部连接,这样我就得到了上面的结果。 如果 C 中缺少任何一列,它应该产生 null。 如果我进行内部连接:

select a.id, b.age where a.id = c.id and b.age = c.age

我会取回 3 行。 我还想要 5 行回来。我正在使用 IBM db2 v9 的东西。 我试图弄清楚如何使用较新的左外连接语法来实现它,但我没有看到它。 我可以看到如何在旧的 sybase *= 外连接语法中做到这一点,但我看不到如何以新的方式做到这一点。 这甚至可能吗?

有人建议将每个结果的一半合并。在我看来,工会只会弄得一团糟,我应该能够从两个表中进行左外连接。

帮助? 谢谢。

【问题讨论】:

  • 你在用什么RDBMSRDBMS 代表关系数据库管理系统RDBMS is the basis for SQL,适用于所有现代数据库系统,如 MS SQL Server、IBM DB2、Oracle、MySQL 等...
  • ibm db2。我认为这是第 9 版。
  • ...你为什么想要空值?他们并没有真正告诉你任何有用的信息。
  • 因为这是我实际所做的一个非常简化的示例。在我实际执行的更大查询的结果集中还有其他有用的信息。
  • 我知道唯一可行的方法是将 a+b 转换为派生表,然后我可以在 ab 和 c 之间进行左外连接。但在现实世界的情况下,a 和 b 都已经是非常复杂的派生表。我希望我缺少一个 sql 语法。

标签: sql db2 outer-join


【解决方案1】:

你是这个意思吗?

SELECT a.id, b.age
FROM a
CROSS JOIN b
LEFT OUTER JOIN c on a.id = c.id AND b.age = c.age

您的问题不清楚是否交叉连接 A 和 B 或 B 是否也保持连接:

SELECT a.id, b.age
FROM a
LEFT OUTER JOIN c on a.id = c.id
LEFT OUTER JOIN b on b.age = c.age

还有更多可能的组合...

【讨论】:

  • 我试过这个,但 db2 似乎对这种语法犹豫不决。实际上我尝试了一些不同的方法,让我举个例子,谢谢。
  • 不行,我得到了笛卡尔类型的结果。它生成了 id 和 age 的每一个组合。但这是个好主意,谢谢。
【解决方案2】:
-- A Dummy table
with A as (
  select
    2 as id
  from
    sysibm.sysdummy1)

-- B Dummy table
, B as (
  select
    6 as age
  from
    sysibm.sysdummy1)

-- C Dummy table    
, C as (
  select
    2 as id,
    0 as age
  from
    sysibm.sysdummy1)


-- Actual result query
select
  A.id as "A.id",
  B.age as "B.age",
  C.id as "C.id",
  C.age as "C.age",
  case
    when A.id = C.id and B.age = C.age then
      C.id
    else
      null
  end as "result id",
  case
    when A.id = C.id and B.age = C.age then
      C.age
    else
      null
  end as "result age"
from
  sysibm.sysdummy1 as Dummy
  left outer join A as A on 1=1
  left outer join B as B on 1=1
  left outer join C as C on 1=1

这是我的解决方案,它将产生与原始帖子匹配的结果。只需将 A、B 和 C 虚拟表中的值替换为提供的示例即可。

编辑: 不使用 case 语句的结果相同:

select
  A.id as "A.id",
  B.age as "B.age",
  C.id as "C.id",
  C.age as "C.age",
  R.id as "result id",
  R.age as "result age"
from
  sysibm.sysdummy1 as Dummy
  left outer join A as A on 1=1
  left outer join B as B on 1=1
  left outer join C as C on 1=1
  left outer join C as R 
    on A.id = R.id
    and B.age = R.age

【讨论】:

    【解决方案3】:

    这是对这个问题的较晚回复,但下面的查询应该可以做到。

    我在http://sqlfiddle.com/#!3/07d74/5创建了一个在线sqlfiddle

    您可以使用上面的在线 sqlfiddle 验证您的要求。它给出的结果与您要求的完全相同。

    即使经过大量的谷歌搜索,我也找不到用于运行 DB2 查询的在线工具,但在提出这个查询之前,我检查了 IBM 的关于 DB2 语法的交叉联接和左联接的文档。所以,它应该可以在 DB2 中工作,但是如果您发现任何问题,请告诉我。 如果您知道 DB2 的在线工具,请告诉我。 sqlfiddle 基于 Sql Server,因为 sqlfiddle 上没有 DB2 选项,但正如我所说,根据我阅读的文档,查询与 DB2 兼容。

    DB2 兼容查询如下。

     SELECT D.id,
           D.age
    FROM C
    LEFT OUTER JOIN
      (SELECT A.id,
              B.age
       FROM A
       CROSS JOIN B) D ON D.id = C.id
    AND D.age = C.age;
    

    【讨论】:

      【解决方案4】:

      对于不完整且不正确的“FULL JOIN”帖子,我们深表歉意。

      会不会:

      select case when b.age is not null then a.id end as id
           , case when a.id is not null then b.age end as age
      from c
        left join a on a.id  = c.id
        left join b on b.age = c.age
      

      【讨论】:

      • ...恐怕你需要提供一个实际的例子
      • 你能解释一下如何交叉连接三个表吗?这个对我来说是新的。
      • 我查了一下,完全联接会给我一个笛卡尔积,这是我不想要的。
      • @stu:完全外连接不是交叉连接。它完全不同
      • 是的,我说错了,但完全加入仍然对我不起作用。
      猜你喜欢
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-29
      • 1970-01-01
      相关资源
      最近更新 更多