具有开始日期和结束日期以及数据透视的历史表

时间:2019-02-06 14:36:46

标签: sql oracle date pivot common-table-expression

我有一个历史记录表。

条件:

min日期从date_asgn开始start_cycle 在下一个日期之前第二个周期结束。 只需要当天的最新日期,与担任哪个职位无关。

PKID    ID   CUSTID  ROLE      Date_ASGN
 1      45    4565   Primary   12/20/2018 3:12:24 PM
 2      45    4025   Secondary 12/20/2018 3:12:24 PM
 3      45    594    Primary   1/2/2019 4:09:58 PM

我的预期输出:

ID START_CYCLE          END_CYCLE          PRIMARY  SECONDARY  BACKUP
45  12/20/2018 3:12:24  1/2/2019 4:09:57   4565       4025      NULL
45  1/2/2019   4:09:58  12/31/9999         594        4025      NULL

我当前的SQL。

SELECT
A.ID,
A.DATE_ASGN AS START_CYCLE,
CASE WHEN LEAD (A.DATE_ASGN ) OVER (PARTITION BY A.ID ORDER BY A.DATE_ASGN ) = TRUNC(A.DATE_ASGN ) THEN NULL 
ELSE LEAD (A.DATE_ASGN ) OVER (PARTITION BY A.ID ORDER BY A.DATE_ASGN ) - NUMTODSINTERVAL(1,'second')
END AS END_CYCLE,
'' AS [PRIMARY],
'' AS SECONDARY
'' AS [BACKUP]

FROM (SELECT * FROM (SELECT H.*,DENSE_RANK() OVER (PARTITION BY ID,TRUNC(H.DATE_ASGN) ORDER BY H.DATE_ASGN DESC,PK DESC) RNK
  FROM  H
  WHERE H.ID = 45
                          )
                          WHERE RNK = 1) A

输出:

 ID  START_CYCLE            END_CYCLE           PRIMARY  SECONDARY  BACKUP
 45   12/20/2018 3:12:24 PM 1/2/2019 4:09:57 PM  
 45   1/2/2019 4:09:58      12/31/9999

需要执行哪些其他步骤才能获得预期的输出。我当时正在考虑将我的SQL转换为CTE并从那里开始工作,但不确定从哪里开始。

2 个答案:

答案 0 :(得分:0)

您已经具有解决方案的要素。因此,理解下面的代码应该不会有太多麻烦。不过请根据需要询问后续问题。

请注意中间步骤,即我称为p的CTE-当我们使用pivot运算符(在本例中为列PKID)时,我们需要摆脱不需要的列,并且我在此中间步骤中放入了额外的过滤器where id = 45

with
  h (pkid, id, custid, role, date_asgn) as (
    select 1, 45,  4565, 'Primary'  , to_date('12/20/2018 3:12:24 PM'
                                , 'mm/dd/yyyy hh:mi:ss AM') from dual union all
    select 2, 45,  4025, 'Secondary', to_date('12/20/2018 3:12:24 PM'
                                , 'mm/dd/yyyy hh:mi:ss AM') from dual union all
    select 3, 45,   594, 'Primary'  , to_date('1/2/2019 4:09:58 PM  '
                                , 'mm/dd/yyyy hh:mi:ss AM') from dual
  )
, p as (select id, custid, role, date_asgn from h where id = 45)
select id, date_asgn as start_cycle,
       lead(date_asgn, 1, date '9999-12-31') over (order by date_asgn) end_cycle,
       last_value(primary   ignore nulls)    over (order by date_asgn) primary,
       last_value(secondary ignore nulls)    over (order by date_asgn) secondary,
       last_value(backup    ignore nulls)    over (order by date_asgn) backup
from   p
pivot  (max(custid) for role in ('Primary' primary, 'Secondary' secondary,
                                                       'Backup' backup))
;

ID START_CYCLE            END_CYCLE                 PRIMARY  SECONDARY     BACKUP
-- ---------------------- ---------------------- ---------- ---------- ----------
45 12/20/2018 03:12:24 PM 01/02/2019 04:09:58 PM       4565       4025           
45 01/02/2019 04:09:58 PM 12/31/9999 12:00:00 AM        594       4025   

答案 1 :(得分:0)

您是否只想按iddate_asn的日期部分进行汇总?

select id, min(date_asn) as start_cycle, max(date_asn) as end_cycle,
       max(case when role = 'Primary' then custid end) as primary,
       max(case when role = 'Secondary' then custid end) as secondary,
       max(case when role = 'Backup' then custid end) as backup
from t
group by id, trunc(date_asn);

如果您要用最新的非secondary次要填充NULL

select id, min(date_asn) as start_cycle, max(date_asn) as end_cycle,
       max(case when role = 'Primary' then custid end) as primary,
       lag(max(case when role = 'Secondary' then custid end) ignore nulls) over (partition by id order by min(date_asn)) as secondary,
       max(case when role = 'Backup' then custid end) as backup
from t
group by id, trunc(date_asn);