sql - SQL 操作
问题描述
以下是表结构和数据
输入:
S_ID PREV_STD NEXT_STD CHG_DT
------------------------------------------
1 3 4 23-NOV-16
1 4 5 20-NOV-17
1 5 6 17-NOV-18
2 3 4 20-NOV-17
3 3 4 23-NOV-16
我想在下面转换上面的内容:09-DEC-18 是系统日期,01-JAN-00 是每个学生第一个标准的开始日期。
期望的输出:
S_ID PREV_STD NEXT_STD START_DT END_DT
--------------------------------------------------
1 3 4 01-JAN-00 22-NOV-16
1 4 5 23-NOV-16 19-NOV-17
1 5 6 20-NOV-17 16-NOV-18
1 6 6 17-NOV-18 09-DEC-18
2 3 4 01-JAN-00 19-NOV-17
2 4 4 20-NOV-17 09-DEC-18
3 3 4 01-JAN-00 22-NOV-16
3 4 4 23-NOV-16 09-DEC-18
我的尝试(正在进行中):
with input as
(
select 1 s_id, 3 prev_std, 4 next_std, to_date('20161123', 'YYYYMMDD') chg_dt
from dual
union all
select 1 s_id, 4, 5, to_date('20171120', 'YYYYMMDD')
from dual
union all
select 1 s_id, 5, 6, to_date('20181117', 'YYYYMMDD')
from dual
union all
select 2 s_id, 3, 4, to_date('20171120', 'YYYYMMDD')
from dual
union all
select 3 s_id, 3, 4, to_date('20161123', 'YYYYMMDD')
from dual
)
select
S_ID, PREV_STD, NEXT_STD,
NVL(lag(CHG_DT) over(partition by s_id order by chg_dt),
to_date('20000101','YYYYMMDD')) start_dt,
CHG_DT - 1 stop_dt,
CHG_DT,
NVL(lead(CHG_DT) over(partition by s_id order by chg_dt), sysdate) next_start_dt,
count(1) over(partition by s_id order by chg_dt) rec_num,
count(1) over(partition by s_id) rec_to_process
from
input;
解决方案
完成了我的解决方案。
with input as(
select
1 s_id,
3 prev_std,
4 next_std,
to_date('20161123', 'YYYYMMDD') chg_dt
from
dual
UNION ALL
select
1 s_id,
4,
5,
to_date('20171120', 'YYYYMMDD')
from
dual
UNION ALL
select
1 s_id,
5,
6,
to_date('20181117', 'YYYYMMDD')
from
dual
UNION ALL
select
2 s_id,
3,
4,
to_date('20171120', 'YYYYMMDD')
from
dual
UNION ALL
select
3 s_id,
3,
4,
to_date('20161123', 'YYYYMMDD')
from
dual
)
select
*
from
(
select
S_ID,
PREV_STD,
NEXT_STD,
NVL(
lag(CHG_DT) over(
partition by s_id
order by
chg_dt
),
to_date('20000101', 'YYYYMMDD')
) start_dt,
CHG_DT - 1 stop_dt
from
input
UNION ALL
select
S_ID,
NEXT_STD,
NEXT_STD,
CHG_DT,
sysdate
from
(
select
S_ID,
NEXT_STD,
CHG_DT,
count(1) over(
partition by s_id
order by
chg_dt
) rec_num,
count(1) over(partition by s_id) rec_to_process
from
input
)
where
rec_num = rec_to_process
)
order by
S_ID,
start_dt;
推荐阅读
- c++ - boost::get with boost::filtered_graph on adjacency_list with netsed properties
- c# - 如何管理重复的程序集引用 C# Unity / 如何使用标志编译 C# 项目
- django - 防止 Django 必填表单字段上的 html5“必填”属性
- c++ - OSX(brew)上 BOOST_ROOT 和 BOOST_LIBRARY_DIR 的正确位置?
- javascript - 从 YT API JSON 获取 YouTube 横幅
- assembly - 打印出一个 3 位数字让我溢出
- python - 将值从嵌套类传播到基类
- jquery - Jquery获取选定div的多个锚文本
- typescript - 升级 TypeScript 版本 + 无关错误
- r - R,dplyr,根据R中的一个条件列有条件地更改多列中的值