sql - Postgres 重叠日期范围以供查看

标签 sql postgresql

我有三个表

    Table 1              Table 2             Table 3
   start_date          start_date          start_date
   end_date            end_date             end_date
    val                   val                  val

现在假设我在表中有以下内容:

Table 1
start_date    end_date     val
01-01-2000     31-01-2000   APPLE
01-02-2000                  ORANGE

table 2
start_date    end_date     val
01-01-2000     15-01-2000   TOMATO
16-01-2000                  LETTUCE

table 3
start_date    end_date     val
01-12-1999                  CAR

我希望将以上三个表放入具有最小/最大日期的 View 中。看起来像这样:

start_date     end_date      val_table_1    val_table_2    val_table_3
01-12-1999     31-12-1999       null           null           CAR
01-01-2000     15-01-2000       APPLE          TOMATO         CAR
16-01-2000     31-01-2000       APPLE          LETTUCE        CAR
01-02-2000                      ORANGE         LETTUCE        CAR

最佳答案

我能够通过下面的查询获得想要的结果。也可在此处作为演示获得 SQL Fiddle .如果创建 View ,请省略最后的 order by 子句,将其包含在此处只是为了合理地呈现结果。

PostgreSQL 9.6 架构设置:

CREATE TABLE Table1
    ("start_date" timestamp, "end_date" timestamp, "val" varchar(20))
;

INSERT INTO Table1
    ("start_date", "end_date", "val")
VALUES
    ('2000-01-01 00:00:00', '2000-01-31', 'APPLE'),
    ('2000-02-01 00:00:00', NULL, 'ORANGE')
;

CREATE TABLE Table2
    ("start_date" timestamp, "end_date" timestamp, "val" varchar(20))
;

INSERT INTO Table2
    ("start_date", "end_date", "val")
VALUES
    ('2000-01-01', '2000-01-15', 'TOMATO'),
    ('2000-01-16', NULL, 'LETTUCE')
;

CREATE TABLE Table3
    ("start_date" timestamp, "end_date" timestamp, "val" varchar(3))
;

INSERT INTO Table3
    ("start_date", "end_date", "val")
VALUES
    ('1999-01-12 00:00:00', NULL, 'CAR')
;

查询 1:

with ends as (
          select end_date from Table1 where end_date is not null union
          select end_date from Table2 where end_date is not null union
          select end_date from Table3 where end_date is not null
          )
select
       d.start_date
     , least(e.end_date, lead(d.start_date,1) over(order by d.start_date) - INTERVAL '1 DAY') as end_date
     , table1.val as t1_val
     , table2.val as t2_val
     , table3.val as t3_val
from (
    select start_date from Table1 union
    select start_date from Table2 union
    select start_date from Table3
    ) d
left join lateral (
  select ends.end_date from ends where ends.end_date > d.start_date
  order by end_date
  limit 1
  ) e on true
left join table1 on d.start_date between table1.start_date and coalesce(table1.end_date,current_date)
left join table2 on d.start_date between table2.start_date and coalesce(table2.end_date,current_date)
left join table3 on d.start_date between table3.start_date and coalesce(table3.end_date,current_date)
order by
       start_date, end_date

Results :

|           start_date |             end_date | t1_val |  t2_val | t3_val |
|----------------------|----------------------|--------|---------|--------|
| 1999-01-12T00:00:00Z | 1999-12-31T00:00:00Z | (null) |  (null) |    CAR |
| 2000-01-01T00:00:00Z | 2000-01-15T00:00:00Z |  APPLE |  TOMATO |    CAR |
| 2000-01-16T00:00:00Z | 2000-01-31T00:00:00Z |  APPLE | LETTUCE |    CAR |
| 2000-02-01T00:00:00Z |               (null) | ORANGE | LETTUCE |    CAR |

关于sql - Postgres 重叠日期范围以供查看,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50302792/

相关文章:

php - 获取所有新闻和所有评论

postgresql - Grails 2.5.11/Postgresql 10,在GSP中上传图像并显示

java - Hibernate 正在提交但不保存

SQL 查询将字段递增该字段中的前一个数字

mysql - 如何从包括子查询在内的SQL查询中选择所有

sql - 数据透视表可以用于未知数量的列吗?

php - 如何在 PHP 中列出来自 MySQL 的规范化数据?

sql - 删除重复行但保留最早的行(按日期标准) - SQL Server

sql - 在数据库中存储时间温度数据

spring - TypeMismatchException 提供的 ID 类型错误