2012-07-06 48 views
0

我需要您的帮助来解决Oracle SQL中的以下问题。只有在值不变时折叠日期记录 - Oracle SQL

表1(输入)

Emp_ID Start_Date End_Date Rating Department Salary 
2000 01012011 01012012 A HR   10000 
2000 01012012 01012013 A+ HR   20000 
2000 01012013 12319999 A HR   20000 
3000 01012011 01012012 B Operations 50000 
3000 01012012 12319999 B Operations 60000 

表2(输出)

Emp_ID Start_Date End_Date Rating Department 
2000 01012011 12312011 A HR 
2000 01012012 12312012 A+ HR 
2000 01012013 12319999 A HR 
3000 01012011 12319999 B Operations 

折叠的最新记录只有在雇员的评级是相同的下一个连续的时间范围,它应继续,直到等级变化..

我希望我的问题明确..

我看了看其他的答案想通,我需要超前和滞后的功能。但是,如果有人可以提供关于如何启动,这将是巨大的光..

感谢

+0

任何帮助家伙..我真的很努力解决这个问题.. – javanoob 2012-07-06 14:13:30

回答

1

这似乎是一个有点复杂,所以我会对改进感兴趣。

select distinct emp_id, 
    nvl(x_start_date, 
     lag(x_start_date) 
      over (partition by emp_id 
       order by rn)) as start_date, 
    nvl(x_end_date, 
     lead(x_end_date) 
      over (partition by emp_id 
       order by rn nulls first)) 
        as end_date, 
     rating, 
     department 
from (
    select emp_id, start_date, end_date, rating, department, 
     case start_date 
      when lag(end_date) 
       over (partition by emp_id, rating, department 
        order by start_date) then null 
      else start_date end as x_start_date, 
     case end_date 
      when lead(start_date) 
       over (partition by emp_id, rating, department 
        order by start_date) then null 
      else end_date end as x_end_date, 
     rownum as rn 
    from table1 
) 
where x_start_date is not null or x_end_date is not null 
order by emp_id, start_date 
/

有了这个测试数据:

EMP_ID START_DA END_DATE RA DEPARTMENT    SALARY 
---------- -------- -------- -- -------------------- ---------- 
     2000 01012010 01012011 A HR       9000 
     2000 01012011 01012012 A HR      10000 
     2000 01012012 01012013 A+ HR      20000 
     2000 01012013 01012014 A HR      20000 
     2000 01012014 12319999 A HR      21000 
     3000 01012011 01012012 B Operations    50000 
     3000 01012012 12319999 B Operations    60000 
     4000 07012011 07012012 B Operations    50000 
     4000 07012012 07012013 B Operations    50000 
     4000 07012013 12319999 B Operations    60000 

我得到这个:

EMP_ID START_DA END_DATE RA DEPARTMENT 
---------- -------- -------- -- -------------------- 
     2000 01012010 01012012 A HR 
     2000 01012012 01012013 A+ HR 
     2000 01012013 12319999 A HR 
     3000 01012011 12319999 B Operations 
     4000 07012011 12319999 B Operations 

我还与emp_id4000)试过有三个连续的日期范围,并处理确定 - 外层where子句使中间条目基本消失。 编辑为添加:现在也适用于2000/A的额外日期范围,因为我在lead//lag分区中修正了排序。

内部查询空白出所有但第一开始日期和最后结束日期的连续块,并且外查询使用一第二轮leadlag将它们合并到相同的行,其distinct然后崩溃。

我假设start_dateend_dateDATE领域,不VARCHAR2,你必须NLS_DATE_FORMAT设置为MMDDYYYY。如果将它们存储为字符串,这是一个糟糕的主意,您需要在相当多的地方使用to_date()才能使订购正常工作。

+0

嗨亚历克斯,你的代码几乎工作,但我已经尝试了下面的情况下,它不工作。我添加日期01012010 - 01012011为emp_id 2000的评分'A'和01012013 - 01012014为emp_id 2000的评分'A'..有没有办法可以添加此..我知道这是太多的要求:)谢谢 – javanoob 2012-07-09 15:31:37

+0

@javanoob:排序在外部功能搞砸了;我添加了'rownum'伪序列到内部选择并且改变了'lead' /'lag'以按顺序排列,以保留在内部选择中完成的工作。我认为结果是现在... – 2012-07-09 16:35:44

+0

非常感谢你alex..but但我没有得到相同的结果,因为你得到了..是你使用相同的查询?我在输出中看到很少的空值..我真的很抱歉打扰你.. – javanoob 2012-07-09 17:28:58

1
select * 
from inputtable it1 
left join inputtable it2 
     on it1.emp_id = it2.emp_id 
     and it1.rating = it2.rating 
     and it1.start_date < it2.start_date 
     and not exists(select * from inputtable it2a 
        where it1.emp_id = it2a.emp_id 
         and ((it1.rating <> it2a.rating 
         and it1.start_date < it2a.start_date 
         and it2.start_date > it2a.start_date) 
         or (it1.rating = it2a.rating 
         and exists(select * from inputtable it2b 
            where it2a.emp_id = it2b.emp_id 
             and it2a.rating = it2b.rating 
             and it2a.end_date + 1 = it2b.start_date)))) 
where not exists(select * from inputtable it1a 
       where it1.emp_id = it1a.emp_id 
        and it1.rating = it1a.rating 
        and it1.start_date = it1a.end_date + 1) 
+0

几乎在那里,但不完全。 OP似乎想要显示折叠范围,而不仅仅是评级更改前的最后一个子范围。 – 2012-07-06 04:37:21

+0

谢谢设置,但它并没有真正服务于我的阴户,因为Andiry M提到.. – javanoob 2012-07-06 14:13:12

+0

对,我忽略了End_Date应该来自另一行(因此额外的左连接)。答复修改。 – Set 2012-07-06 15:57:50

相关问题