PSQL左外连接不返回不匹配连接的值

时间:2018-06-17 21:36:00

标签: sql postgresql outer-join

Left-Outer Join in Postgres Not Returning Values for Null相似,但解释并没有改善我的情况。

我的期望是,当未指定的方向(与指定的左/右相反)没有匹配时,外部联接保留指定的方向(左或右),同时放置空值。我以前在另一个数据库上成功使用过它,但不再能够访问示例代码。

这是我正常运作的玩具示例:

with complete as (
        select generate_series(
            '2018-06-15'::date,
            '2018-06-17'::date,
            '1 day'::interval
        )::date as date
    ), incomplete as (
        select *
        from (
            values('2018-06-15'::date),('2018-06-17'::date)
        ) as foo(date)
    )
    select
        complete.date as complete
        , incomplete.date as incomplete
    from complete
    left outer join incomplete using(date)
;

结果如预期:

  complete  | incomplete
------------+------------
 2018-06-15 | 2018-06-15
 2018-06-16 |
 2018-06-17 | 2018-06-17
(3 rows)

现在使用真实数据是相同的事情:

with alldates as (
        select

            generate_series(
                min(datetime::date),
                max(datetime::date),
                '1 day'::interval
            )::date as date

        from garagetime
    ), datadates as (
        select distinct datetime::date as date
        from garagetime
    )
    select
        alldates.date as alldate
        , datadates.date as datadate
    from alldates
    left outer join datadates using(date)
;

没有按预期工作:

  alldate   |  datadate
------------+------------
 2016-08-10 | 2016-08-10
 2016-08-11 | 2016-08-11
 2016-08-12 | 2016-08-12 -- skips right over 13..16
 2016-08-17 | 2016-08-17 -- skips again
 2016-08-22 | 2016-08-22
 2016-08-23 | 2016-08-23
 ...

预期结果:

  alldate   |  datadate
------------+------------
 2016-08-10 | 2016-08-10
 2016-08-11 | 2016-08-11
 2016-08-12 | 2016-08-12
 2016-08-13 |            -- nulls, as expected
 2016-08-14 | 
 2016-08-15 | 
 2016-08-16 | 
 2016-08-17 | 2016-08-17
 2016-08-18 | 
 2016-08-19 | 
 2016-08-20 | 
 2016-08-21 | 
 2016-08-22 | 2016-08-22
 2016-08-23 | 2016-08-23
 ...

我尝试左/右切换连接,切换连接中指定表名的顺序(虽然我非常有信心我知道何时根据结果使用“left”vs“right” m试图获取),使用“ON alldates.date = datadates.date”代替“USING(date)”,将“AS date”列重命名为“date”以外的其他内容。

而不是:

select
    alldates.date as alldate
    , datadates.date as datadate

我也试过这个:

select
    alldates.date as alldate
    , case
        when alldates.date=datadates.date then alldates.date
        else null
    end as datadate

和此:

select
    alldates.date
    , datadates.date

一旦我删除了连接,查询就会返回所有日期,但在这种情况下,我看不到哪些日期丢失。

1 个答案:

答案 0 :(得分:1)

评论太长了。我怀疑 正常工作,但结果不符合您的预期。

添加order by是否按所需顺序显示所有日期?

select alldates.date as alldate,
       datadates.date as datadate
from alldates left outer join
     datadates
     using(date)
order by alldates.date;