【问题标题】:Left Outer Join where NULL in Left tableLeft Outer Join where NULL in Left table
【发布时间】:2018-12-04 17:28:34
【问题描述】:

我有以下表格:

ITEM_TABLE            TYPE_TABLE
--------------      -------------------
|Item|Type_ID|      |Type_ID|Type_Text|
--------------      -------------------
|  A |  3    |      |   1   | Table   |
|  B |  1    |      |   2   | Chair   |
|  C |  1    |      |   3   | Bench   |
|  D |  2    |      -------------------
|  E | NULL  |
|  F |  2    |
|  G |  1    |
|  H |  3    |
--------------

我希望我的结果显示一个对类型有意义的字符串,所以我加入了两个表:

select 
    it.Item, tt.Type_ID
from 
    ITEM_TABLE it
    left outer join TYPE_TABLE tt
        on it.Type_ID = tt.Type_ID

结果是:

----------------
|Item|Type_Text| 
----------------
|  A | Bench   |
|  B | Table   |
|  C | Table   |
|  D | Chair   |
|  F | Chair   |
|  G | Table   |
|  H | Bench   | 
----------------

注意项目E没有行,因为它有一个为NULL的ITEM_TABLE.Type_ID,并且该值不能满足it.Type_ID = tt.Type_ID的连接条件。

但是,我想要的结果是:

----------------
|Item|Type_Text| 
----------------
|  A | Bench   |
|  B | Table   |
|  C | Table   |
|  D | Chair   |
|  E | NULL    | * note this row here, not present in the actual result
|  F | Chair   |
|  G | Table   |
|  H | Bench   | 
----------------

我试过了:

select 
    it.Item, tt.Type_ID
from 
    ITEM_TABLE it
    left outer join TYPE_TABLE tt
        on it.Type_ID = tt.Type_ID or it.Type_ID is null

但这给出了结果:

----------------
|Item|Type_Text| 
----------------
|  A | Bench   |
|  B | Table   |
|  C | Table   |
|  D | Chair   |
|  E | Table   |
|  E | Chair   |
|  E | Bench   |
|  F | Chair   |
|  G | Table   |
|  H | Bench   | 
----------------

也就是说,E 项的三行,每行都有一个可能的TYPE_TABLE.Type_Text 值。

那么我怎样才能得到我想要的结果,连接语句意识到ITEM_TABLE.Type_ID 列中的NULL 值应该在结果的Type_Text 列中给出NULL 值?

【问题讨论】:

  • 也许使用RIGHT JOIN
  • 发布的原始查询应该可以工作。这与您实际使用的查询完全相同吗?
  • 尝试简单加入
  • 这肯定不是至少它在 SQL Server 中的工作方式 - 该行仍然应该通过。这是一个什么样的数据库?通常犯的错误是在查询中进一步过滤 NULL(使其成为内部连接)

标签: sql left-join outer-join


【解决方案1】:

这个查询:

select it.Item, tt.Type_ID
from ITEM_TABLE it left outer join
     TYPE_TABLE tt
     on it.Type_ID = tt.Type_ID

将返回ITEM_TABLE 中的每一行,无论on 子句的计算结果是否为TRUEFALSENULL。这是一个rextester 证明所有行都已返回。尽管 rextester 使用 Postgres,但您在任何数据库中都会得到相同的行为,因为 SQL 就是这样工作的。

现在,如果你想要一个字符串,你应该选择字符串,而不是 id。当不匹配时,您可以使用coalesce() 提供另一个值:

select it.Item, coalesce(type_text, 'default')
from ITEM_TABLE it left outer join
     TYPE_TABLE tt
     on it.Type_ID = tt.Type_ID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多