如何创建一个与一个日期列没有间隔的开始日期和结束日期,以及如何对日期内的值求和
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 中的 运行 示例。
我是 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 中的 运行 示例。