我需要通过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
答案 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