gpt4 book ai didi

sql - 如何合并连续的日期范围 Oracle

转载 作者:行者123 更新时间:2023-12-04 13:55:22 25 4
gpt4 key购买 nike

我正面临一个问题。我不知道如何根据两个维度将连续的日期范围行合并在一起。一个对我来说还可以,但第二个就麻烦了

让我们想象一下这种结构中的表格有四种可能的情况

  emp_id  |  level  |  date_from   |   date_to    
--------------------------------------------------
1 | A | 7/31/2015 | 3/31/2016
1 | A | 4/1/2016 | 1/1/3000

2 | A | 7/31/2015 | 1/1/3000

3 | A | 5/31/2015 | 12/31/2015
3 | B | 1/1/2016 | 3/31/2016
3 | A | 4/1/2016 | 6/30/2016
3 | B | 7/1/2016 | 1/1/3000

4 | A | 5/31/2015 | 12/31/2015
4 | A | 1/1/2016 | 6/30/2016
4 | B | 7/1/2016 | 1/1/3000

我只想合并那些具有连续日期范围的行 和 act_level = prev_level

我试图做这样的事情
SELECT emp_id
, level
, date_from
, date_to
--
, CASE
WHEN lag(level) over (partition by emp_id order by date_from) = level THEN
CASE
WHEN lag(date_to) over (partition by emp_id, level order by date_from) = date_from-1
THEN lag(date_from) over (partition by code_employee, level_name order by date_from)
ELSE NULL
END
ELSE
CASE
WHEN lag(level) over (partition by emp_id order by date_from) = level
OR
lead(level) over (partition by emp_id order by date_from) = level
THEN NULL
ELSE date_from
END
END date_from_new
, date_to as date_to_new
--
FROM src_table
--
WHERE 1=1

这给了我几乎我想要的结果:
  emp_id  |  level  |  date_from   |   date_to   |  d_from_new | d_from_to 
--------------------------------------------------------------------------
1 | A | 7/31/2015 | 3/31/2016 | | 3/31/2016
1 | A | 4/1/2016 | 1/1/3000 | 7/31/2015 | 1/1/3000

2 | A | 7/31/2015 | 1/1/3000 | 7/31/2015 | 1/1/3000

3 | A | 5/31/2015 | 12/31/2015 | 5/31/2015 | 12/31/2015
3 | B | 1/1/2016 | 3/31/2016 | 1/1/2016 | 3/31/2016
3 | A | 4/1/2016 | 6/30/2016 | 4/1/2016 | 6/30/2016
3 | B | 7/1/2016 | 1/1/3000 | 7/1/2016 | 1/1/3000

4 | A | 5/31/2015 | 12/31/2015 | | 12/31/2015
4 | A | 1/1/2016 | 6/30/2016 | 5/31/2015 | 6/30/2016
4 | B | 7/1/2016 | 1/1/3000 | 7/1/2016 | 1/1/3000

我将只过滤 d_from_new (date_from_new) 而非空值的结果。但是我不确定如果连续日期范围内有相同级别的 3 倍或 8 倍会发生什么。

老实说 - 我不喜欢这个查询:)

你有任何“性能友好”和“眼睛友好”的解决方案吗?

最佳答案

请试试这个查询:

select emp_id, lvl, min(date_from) df, max(date_to) dt
from (
select s2.*, rn - sum(marker) over (order by rn) as grp
from (
select s1.*,
row_number() over (order by emp_id, date_from) rn,
case when lag(lvl) over (partition by emp_id order by date_from)
= lvl
and lag(date_to) over (partition by emp_id order by date_from) + 1
= date_from
then 1
else 0
end marker
from src_table s1 ) s2 )
group by emp_id, lvl, grp
order by emp_id, min(date_from)

在第一个子查询中 S1我添加了标记,如果前一级别对应且日期连续,则分配 1。在第二个子查询中,此标记用于构建 GRP所有匹配行都具有相同值的列。此列用于最终分组查询以查找最小值 date_from最大 date_to .请单独运行内部查询以查看每个步骤中发生的情况。测试是否有两个以上的连续行。

测试数据和输出:
create table src_table (emp_id number(6), lvl varchar2(2), date_from date, date_to date);
insert into src_table values (1, 'A', date '2015-07-31', date '2016-03-31');
insert into src_table values (1, 'A', date '2016-04-01', date '3000-01-01');
insert into src_table values (2, 'A', date '2015-07-31', date '3000-01-01');
insert into src_table values (3, 'A', date '2015-05-31', date '2015-12-31');
insert into src_table values (3, 'B', date '2016-01-01', date '2016-03-31');
insert into src_table values (3, 'A', date '2016-04-01', date '2016-06-30');
insert into src_table values (3, 'B', date '2016-07-01', date '3000-01-01');
insert into src_table values (4, 'A', date '2015-05-31', date '2015-12-31');
insert into src_table values (4, 'A', date '2016-01-01', date '2016-06-30');
insert into src_table values (4, 'B', date '2016-07-01', date '3000-01-01');

EMP_ID LVL DF DT
------- --- ----------- -----------
1 A 2015-07-31 3000-01-01
2 A 2015-07-31 3000-01-01
3 A 2015-05-31 2015-12-31
3 B 2016-01-01 2016-03-31
3 A 2016-04-01 2016-06-30
3 B 2016-07-01 3000-01-01
4 A 2015-05-31 2016-06-30
4 B 2016-07-01 3000-01-01

8 rows selected

关于sql - 如何合并连续的日期范围 Oracle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39845255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com