令人困惑的差距和岛屿ORACLE SQL

时间:2014-06-09 20:44:01

标签: sql

我需要通过TSK和ACTCODE将以下数据重新排序到Oracle SQL中它们自己的岛中,并按日期排序。新数据将显示TSK,连续组的第一个实例的STARTDATE,连续组的最后一个实例的ENDDATE,其余数据字段都与连续组的最后一个实例(MAX ENDDATE)相关。有没有办法在存储过程之外执行此操作?

感谢您的帮助!

示例数据集:

(之前的数据)

   (Fields) TSK STARTDATE  ENDDATE    ACTCODE    DPTCODE   TSKCODE   OPERID
    1       A   01/06/2014 01/06/2014 2          1587      1584      I511191
    2       A   01/06/2014 01/06/2014 11         1587      1583      I511191
    3       A   01/08/2014 01/08/2014 2          1587      1584      CLARKC
    4       A   01/16/2014 01/16/2014 2          1587      1585      MENDUA

(数据后)

   (Fields) TSK STARTDATE  ENDDATE    ACTCODE    DPTCODE   TSKCODE   OPERID
    1       A   01/06/2014 01/06/2014 2          1587      1584      I511191
    2       A   01/06/2014 01/06/2014 11         1587      1583      I511191
    3       A   01/08/2014 01/16/2014 2          1587      1585      MENDUA

3 个答案:

答案 0 :(得分:2)

基本的“间隙和岛屿”程序是通过取两个连续值之间的差异来识别这些组。在您的情况下,您可以执行此操作以识别组:

select t.*,
       (row_number() over (order by fields) -
        row_number() over (partition by tsk, actcode order by fields)
       ) as grp
from table t

获得你想要的只是更多的工作和聚合:

select min(fields) as fields, min(startdate) as startdate, tsk, max(enddate) as enddate, actcode,
       max(DPTCODE) keep (dense_rank first order by enddate desc),
       max(TSKCODE) keep (dense_rank first order by enddate desc),
       max(OPERID) keep (dense_rank first order by enddate desc)
from (select t.*,
             (row_number() over (order by fields) -
              row_number() over (partition by tsk, actcode order by fields)
             ) as grp
      from table t
     ) t
group by grp, tsk, actcode;

答案 1 :(得分:0)

什么版本的Oracle?如果它是最近的一个,将支持OLAP功能(稍微简化):

select min(startdate) as startdate
     , max(enddate) as enddate
     , actcode
     , grp
from (
    select startdate, enddate, actcode
         , row_number() over (order by startdate)
         - row_number() over (partition by actcode
                              order by startdate) as grp
    from T
) as A
group by actcode, grp

答案 2 :(得分:0)

感谢Gordon的回复!我想我一直都缺少密集等级公式。无论如何,与我的程序完美配合。非常感谢大家的帮助。

with testsomething as (      
select distinct tskid,pidate,operid,starttime,to_date(substr(effdate,5,2)||'/'||substr(effdate,7,2)||'/'||substr(effdate,1,4),'MM/DD/YYYY') as serveffdate,to_date(substr(pidate,5,2)||'/'||substr(pidate,7,2)||'/'||substr(pidate,1,4)||' '||
substr(lpad(starttime,8,0),1,2)||':'||substr(lpad(starttime,8,0),3,2)||':'
||substr(lpad(starttime,8,0),5,2), 'MM/DD/YYYY HH24:MI:SS')  as startdatetime,
to_date(substr(pidate,5,2)||'/'||substr(pidate,7,2)||'/'||substr(pidate,1,4)||' '||
substr(lpad(starttime,8,0),1,2)||':'||substr(lpad(starttime,8,0),3,2)||':'
||substr(lpad(starttime,8,0),5,2), 'MM/DD/YYYY HH24:MI:SS') as enddatetime,
endtime, dptcode,actcode,tskcode from tskhist where tskid in (select tskid from comptsk where compdate between '20140501' and '20140530') and dptcode=1587
order by tskid,pidate, starttime asc)
--,lastoperid as
  --(select distinct tskid,actcode,operid,max(enddatetime) from testsomething group by tskid,operid,actcode)
  ,q AS
        (
        SELECT  tskid,dptcode,actcode,enddatetime,startdatetime,tskcode,serveffdate,operid,
                ROW_NUMBER() OVER (PARTITION BY tskid, actcode ORDER BY startdatetime) AS rnd,
                ROW_NUMBER() OVER (PARTITION BY tskid ORDER BY startdatetime) AS rn
        FROM  testsomething
)
,q2 as (
select min(startdatetime) as startdatetime,max(enddatetime) as enddatetime,tskid,actcode,dptcode,tskcode,serveffdate,max(OPERID) keep (dense_rank first order by enddatetime desc) as operid
from q
GROUP BY
        tskid,actcode,dptcode,tskcode,serveffdate,(rnd - rn) order by tskid,actcode,startdatetime)    


select distinct startdatetime, enddatetime,serveffdate,operid,a.tskid,a.actcode,(case when a.actcode=0 then 'NoAction' else b.actdesc end) as actdesc,a.dptcode,c.dptdesc,a.tskcode,d.tskdesc
from q2 a, acttype b, dpt c, tsktype d
where a.actcode=b.actcode(+) and a.dptcode=c.dptcode(+) and a.tskcode=d.tskcode(+) 
 order by tskid, actcode,startdatetime asc