Sql Postgres全外接式启闭机

Sql Postgres全外接式启闭机,sql,postgresql,join,Sql,Postgresql,Join,如果我编写这样的查询: with foo as ( select 'foo' as name, 1 as value union all select 'foo', 2 union all select 'foo', 3 union all select 'foo', 4 ), bar as ( select 'bar' as name, 3 a

如果我编写这样的查询:

with foo as (
    select
        'foo' as name,
        1 as value
    union all select
        'foo', 2
    union all select
        'foo', 3
    union all select
        'foo', 4
), bar as (
    select
        'bar' as name,
        3 as value
    union all select
        'bar', 4
    union all select
        'bar', 5
    union all select
        'bar', 6
)
select
    f.name,
    b.value,
    b.name
from
    foo as f
full outer join
    bar as b
    on b.value = f.value;
我明白了:

name        value    name
foo         (null)  (null)
foo         (null)  (null)
foo         3       bar
foo         4       bar
(null)      5       bar
(null)      6       bar
这就是我所期望的。但如果我尝试对表值函数执行类似操作,如:

with allSizes as (
        select cast('120X60' as character varying) as size
        union all select '160X600'
        union all select '1X1'
        union all select '300X250'
        union all select '728X90'
        union all select '88X32'
        union all select 'PEEL'
)
select
        msd.region,
        msd.market,
        s.size,
        msd.target,
        msd.actual
from 
        marketdata('2013-01-05') as msd
full outer join
        allSizes as s
        on s.size = msd.size
where
        msd.market = 'Foo, USA';
marketdata()
是一个表值函数时,我不会得到与
size
列对应的空行,这些空行在
marketdata()
函数中不存在。为什么不呢?

这是因为:

where
        msd.market = 'Foo, USA';
它生成
完全外部联接
,然后过滤掉
marketdata()
中不存在的行(因为它们有
msd.market
=
NULL

您可以将查询更改为:

with allSizes as (
        select cast('120X60' as character varying) as size
        union all select '160X600'
        union all select '1X1'
        union all select '300X250'
        union all select '728X90'
        union all select '88X32'
        union all select 'PEEL'
)
select
        msd.region,
        msd.market,
        s.size,
        msd.target,
        msd.actual
from 
        (select marketdata('2013-01-05')
         where  market = 'Foo, USA') as msd
full outer join
        allSizes as s
        on s.size = msd.size;
或者干脆重写

where
        msd.market = 'Foo, USA' OR msd.market IS NULL;
如果
marketdata()
没有返回带有
msd的行。market为NULL

这是因为:

where
        msd.market = 'Foo, USA';
它生成
完全外部联接
,然后过滤掉
marketdata()
中不存在的行(因为它们有
msd.market
=
NULL

您可以将查询更改为:

with allSizes as (
        select cast('120X60' as character varying) as size
        union all select '160X600'
        union all select '1X1'
        union all select '300X250'
        union all select '728X90'
        union all select '88X32'
        union all select 'PEEL'
)
select
        msd.region,
        msd.market,
        s.size,
        msd.target,
        msd.actual
from 
        (select marketdata('2013-01-05')
         where  market = 'Foo, USA') as msd
full outer join
        allSizes as s
        on s.size = msd.size;
或者干脆重写

where
        msd.market = 'Foo, USA' OR msd.market IS NULL;

如果
marketdata()!现在很明显。我很少需要使用完全联接,所以我想得太多了。@JeremyHolovacs:对于“正常”的左或右外部联接也是如此(如果“外部”表的一列是where子句的一部分)。@a_horse_没有名字,是的,这就是为什么我现在说这很明显。允许一个人偶尔发生一次大脑故障。:)哈!现在很明显。我很少需要使用完全联接,所以我想得太多了。@JeremyHolovacs:对于“正常”的左或右外部联接也是如此(如果“外部”表的一列是where子句的一部分)。@a_horse_没有名字,是的,这就是为什么我现在说这很明显。允许一个人偶尔发生一次大脑故障。:)