左外部联接,其中左表为NULL

时间:2018-06-26 05:15:28

标签: sql left-join outer-join

我有下表:

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没有行,因为它的ITEM_TABLE.Type_ID为NULL,并且该值不能满足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值。

因此,如何通过联接语句实现NULL列中的ITEM_TABLE.Type_ID值应在NULL中得到Type_Text值的情况下获得所需的结果结果中的列?

1 个答案:

答案 0 :(得分:0)

此查询:

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子句的计算结果为TRUEFALSE还是NULL。这是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