如何创建一个与一个日期列没有间隔的开始日期和结束日期,以及如何对日期内的值求和

How to create a start and end date with no gaps from one date column and to sum a value within the dates

我是 SQL 编码新手 SQL 开发人员。

我有一个包含 4 列的 table:患者 ID (ptid)、服务日期 (dt)、保险支付金额 (insr_amt)、自付费用金额 (op_amt). (见下文 table 1)

我想做的是 (1) 使用“dt”列创建两列“start_dt”和“end_dt”,如果患者 ID 然后用患者 ID 的第一个和最后一个日期填充开始和结束日期,但是如果患者 ID 中的服务日期存在差距,则为每个患者 ID 创建单独的开始和结束日期行,以及 (2 ) 在一组开始和结束日期访问中按患者 ID 对两次付款金额求和(参见下面的 table 2)。

在 SQL 开发人员中使用 SQL 代码 运行 的方法是什么? 谢谢!

Table 1:

Ptid dt insr_amt op_amt
A 1/1/2021 30 20
A 1/2/2021 30 10
A 1/3/2021 30 10
A 1/4/2021 30 30
B 1/6/2021 10 10
B 1/7/2021 20 10
C 2/1/2021 15 30
C 2/2/2021 15 30
C 2/6/2021 60 30

Table 2:

Ptid start_dt end_dt total_insr_amt total_op_amt
A 1/1/2021 1/4/2021 120 70
B 1/6/2021 1/7/2021 30 20
C 2/1/2021 2/2/2021 30 60
C 2/6/2021 2/6/2021 60 30

您没有提到特定的数据库,因此此解决方案适用于 PostgreSQL。你可以这样做:

select
  ptid,
  min(dt) as start_dt,
  max(dt) as end_dt,
  sum(insr_amt) as total_insr_amt,
  sum(op_amt) as total_op_amt
from (
  select *,
    sum(inc) over(partition by ptid order by dt) as grp
  from (
    select *,
      case when dt - interval '1 day' = lag(dt) over(partition by ptid order by dt)
           then 0 else 1 end as inc
    from t
  ) x
) y
group by ptid, grp
order by ptid, grp

结果:

 ptid  start_dt    end_dt      total_insr_amt  total_op_amt 
 ----- ----------  ----------  --------------  ----------- 
 A     2021-01-01  2021-01-04  120             70           
 B     2021-01-06  2021-01-07  30              20           
 C     2021-02-01  2021-02-02  30              60           
 C     2021-02-06  2021-02-06  60              30           

请参阅 DB Fiddle 1 中的 运行 示例。

编辑 Oracle

根据要求,在 Oracle 中有效的修改后的查询是:

select
  ptid,
  min(dt) as start_dt,
  max(dt) as end_dt,
  sum(insr_amt) as total_insr_amt,
  sum(op_amt) as total_op_amt
from (
  select x.*,
    sum(inc) over(partition by ptid order by dt) as grp
  from (
    select t.*,
      case when dt - 1 = lag(dt) over(partition by ptid order by dt)
           then 0 else 1 end as inc
    from t
  ) x
) y
group by ptid, grp
order by ptid, grp

请参见 db<>fiddle 2 中的 运行 示例。