在PostgreSQL中以NULL显示完整的日期范围

在PostgreSQL中以NULL显示完整的日期范围,postgresql,postgresql-9.4,Postgresql,Postgresql 9.4,我试图创建此查询,以获取范围中的所有完整日期,如果表中不存在日期,则数据为空 例如,这是我的tbl\u示例 原始数据: id | userid(str) | comment(str) | mydate(date) 1 0001 sample1 2019-06-20T16:00:00.000Z 2 0002 sample2 2019-06-21T16:00:00.000Z 3 0003 sample3

我试图创建此查询,以获取范围中的所有完整日期,如果表中不存在日期,则数据为空

例如,这是我的tbl\u示例

原始数据:

id | userid(str) | comment(str) | mydate(date)
1     0001          sample1      2019-06-20T16:00:00.000Z
2     0002          sample2      2019-06-21T16:00:00.000Z
3     0003          sample3      2019-06-24T16:00:00.000Z
4     0004          sample4      2019-06-25T16:00:00.000Z
5     0005          sample5      2019-06-26T16:00:00.000Z
id | userid(str) | comment(str) | mydate(date)
1     0001          sample1      2019-06-20T16:00:00.000Z
2     0002          sample2      2019-06-21T16:00:00.000Z
null  null          null         2019-06-22T16:00:00.000Z
null  null          null         2019-06-23T16:00:00.000Z
4     0003          sample3      2019-06-24T16:00:00.000Z
5     0004          sample4      2019-06-25T16:00:00.000Z 
然后:

select * from tbl_example where mydate between '2019-06-20' AND
DATE('2019-06-20') + interval '5 day')
如何输出可能为空的范围内的所有日期,如下所示

预期输出:

id | userid(str) | comment(str) | mydate(date)
1     0001          sample1      2019-06-20T16:00:00.000Z
2     0002          sample2      2019-06-21T16:00:00.000Z
3     0003          sample3      2019-06-24T16:00:00.000Z
4     0004          sample4      2019-06-25T16:00:00.000Z
5     0005          sample5      2019-06-26T16:00:00.000Z
id | userid(str) | comment(str) | mydate(date)
1     0001          sample1      2019-06-20T16:00:00.000Z
2     0002          sample2      2019-06-21T16:00:00.000Z
null  null          null         2019-06-22T16:00:00.000Z
null  null          null         2019-06-23T16:00:00.000Z
4     0003          sample3      2019-06-24T16:00:00.000Z
5     0004          sample4      2019-06-25T16:00:00.000Z 
这是我的示例测试环境:

结果



好的,只需查看我的SQL,如下所示:

with all_dates as (
select generate_series(min(mydate),max(mydate),'1 day'::interval) as dates from tbl_example
)
,null_dates as (
select
    a.dates
from
    all_dates a
left join
    tbl_example t on a.dates = t.mydate
where
    t.mydate is null
)
select null as id, null as userid, null as comment, dates as mydate from null_dates
union
select * from tbl_example order by mydate;
 id | userid | comment |       mydate        
----+--------+---------+---------------------
  1 | 0001   | sample1 | 2019-06-20 16:00:00
  2 | 0002   | sample1 | 2019-06-21 16:00:00
    |        |         | 2019-06-22 16:00:00
    |        |         | 2019-06-23 16:00:00
  3 | 0003   | sample1 | 2019-06-24 16:00:00
  4 | 0004   | sample1 | 2019-06-25 16:00:00
  5 | 0005   | sample1 | 2019-06-26 16:00:00
(7 rows)
或者在
generate_series
子句中,您可以只编写所需的日期参数,如下所示:

with all_dates as (
select generate_series(min(mydate),max(mydate),'1 day'::interval) as dates from tbl_example
)
,null_dates as (
select
    a.dates
from
    all_dates a
left join
    tbl_example t on a.dates = t.mydate
where
    t.mydate is null
)
select null as id, null as userid, null as comment, dates as mydate from null_dates
union
select * from tbl_example order by mydate;
 id | userid | comment |       mydate        
----+--------+---------+---------------------
  1 | 0001   | sample1 | 2019-06-20 16:00:00
  2 | 0002   | sample1 | 2019-06-21 16:00:00
    |        |         | 2019-06-22 16:00:00
    |        |         | 2019-06-23 16:00:00
  3 | 0003   | sample1 | 2019-06-24 16:00:00
  4 | 0004   | sample1 | 2019-06-25 16:00:00
  5 | 0005   | sample1 | 2019-06-26 16:00:00
(7 rows)
select generate_series('2019-06-20 16:00:00','2019-06-20 16:00:00'::timestamp + '5 days'::interval,'1 day'::interval) as dates

示例不清楚。您的原始数据是什么?您想要什么输出?抱歉,我突出显示了原始数据和预期输出。谢谢shawn.X..请看我的答案,我认为它返回的结果正是您想要的:Dim获取错误:在“userid”位置或附近出现语法错误:35 im使用postgres v9.6作为测试结果没有2019-06-22和2019-06-23,并且没有获得2019-06-20到2019-06-25结果的正确范围。。超过2019-06-27OK。我仍然没有完全理解你的要求。现在我想我知道了。您可以在generate_series函数中看到开始和结束日期。我对它进行了测试,结果显示输出与您要求的相同。嗯,我很困惑“选择生成_系列('2019-06-20 16:00:00'、'2019-06-25 16:00:00'、'1天::间隔)作为日期”并不能使日期范围正确。但是数据更接近预期的输出。@JakeGarbo
generate_series
是构造一个连续的日期周期,然后您可以将tbl_示例数据与其左连接以获取缺失的日期,然后用您获得的日期构造空行,最后合并原始tbl_示例,你会得到你想要的结果。我的样本使用了5天的期限,如果我使用generate_系列(具有适当的日期范围),我没有得到适当的范围,因此我感到困惑。它显示到2019-06-27T00:00:00ZI已经更新了我的以上答案,您可以使用
您的_日期+5天间隔
编写
生成_系列
的第二个参数。我的sql只是一个澄清解决问题的方法的示例,当您了解此方法时,您可以改进它以满足您的需要:D