sql - Postgres 全外连接 headscratcher

标签 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 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 = )

您可以将查询更改为:

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 IS NULL 的行。

关于sql - Postgres 全外连接 headscratcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14219841/

相关文章:

mysql:多重连接问题

MySql查询长时间持续运行

mysql - 当销售日期大于每个 ProductID 订单表中最低的 order_date 时,从销售表中选择行

mysql - 满足 WHERE 子句中的所有条件条件

sql - 删除具有指定参数但在 Postgresql 中最新的所有行

VLOOKUP 的 SQL 版本

c# - 如何从纯文本解析 C# 中的存储过程签名

使用多个数据库时Django错误关系 "auth_user"不存在

postgresql - 删除非空约束

mysql - 选择前一个日期,mysql