Oracle 10g 从两个不同的行和列聚合成一行
Posted
技术标签:
【中文标题】Oracle 10g 从两个不同的行和列聚合成一行【英文标题】:Oracle 10g aggregating from two different rows and columns into a single row 【发布时间】:2018-08-16 11:02:27 【问题描述】:我有一个包含就业开始和结束日期的表格,如下所示:
EEID | EMP_START_DATE | EMP_TERM_DATE
-----+----------------+---------------
1 | 2014-01-01 | null
1 | null | 2014-03-30
1 | 2014-06-01 | null
1 | null | 2014-12-31
1 | 2015-08-01 | null
2 | 2001-07-01 | null
3 | 2010-03-01 | null
3 | null | 2010-03-30
3 | 2010-04-01 | null
3 | null | 2010-04-30
我想将其转换如下,按employeeId (EEID) 和工作期限排序:
EEID | EMP_START_DATE | EMP_TERM_DATE
-----+----------------+---------------
1 | 2014-01-01 | 2014-03-30
1 | 2014-06-01 | 2014-12-31
1 | 2015-08-01 | null
2 | 2001-07-01 | null
3 | 2010-03-01 | 2010-03-30
3 | 2010-04-01 | 2010-04-30
问题
谁能告诉我该怎么做?
【问题讨论】:
【参考方案1】:一种方法是条件聚合。这需要枚举开始和结束,然后使用此枚举进行聚合:
select eeid, max(emp_start_date) as emp_start_date,
max(emp_end_date) as emp_end_date
from (select t.*,
(case when emp_start_date is not null
then count(emp_start_date) over (partition by eeid order by emp_start_date)
else count(emp_end_date) over (partition by eeid order by emp_send_date)
end) as seqnum
from t
) t
group by eeid, seqnum;
【讨论】:
【参考方案2】:当当前行的值为空时,您可以使用领先和滞后来获取上一个/下一个日期值:
select eeid,
emp_start_date as orig_start_date,
emp_term_date as orig_term_date,
coalesce(emp_start_date,
lag(emp_start_date)
over (partition by eeid order by coalesce(emp_start_date, emp_term_date)))
as emp_start_date,
coalesce(emp_term_date,
lead(emp_term_date)
over (partition by eeid order by coalesce(emp_term_date, emp_start_date)))
as emp_term_date
from your_table
order by eeid, emp_start_date, orig_start_date, emp_term_date, orig_term_date;
EEID ORIG_START_DATE ORIG_TERM_DATE EMP_START_DATE EMP_TERM_DATE
---------- --------------- -------------- -------------- -------------
1 2014-01-01 2014-01-01 2014-03-30
1 2014-03-30 2014-01-01 2014-03-30
1 2014-06-01 2014-06-01 2014-12-31
1 2014-12-31 2014-06-01 2014-12-31
1 2015-08-01 2015-08-01
2 2001-07-01 2001-07-01
3 2010-03-01 2010-03-01 2010-03-30
3 2010-03-30 2010-03-01 2010-03-30
3 2010-04-01 2010-04-01 2010-04-30
3 2010-04-30 2010-04-01 2010-04-30
然后消除重复:
select distinct eeid,
coalesce(emp_start_date,
lag(emp_start_date)
over (partition by eeid order by coalesce(emp_start_date, emp_term_date)))
as emp_start_date,
coalesce(emp_term_date,
lead(emp_term_date)
over (partition by eeid order by coalesce(emp_term_date, emp_start_date)))
as emp_term_date
from your_table
order by eeid, emp_start_date;
EEID EMP_START_DATE EMP_TERM_DATE
---------- -------------- -------------
1 2014-01-01 2014-03-30
1 2014-06-01 2014-12-31
1 2015-08-01
2 2001-07-01
3 2010-03-01 2010-03-30
3 2010-04-01 2010-04-30
【讨论】:
谢谢亚历克斯。已将第一个答案标记为正确。投了你的票。赞赏!以上是关于Oracle 10g 从两个不同的行和列聚合成一行的主要内容,如果未能解决你的问题,请参考以下文章