sql - Oracle - Assigning the correct Date from a Set -
i have table below
regid | pkg_desc | event_date | is_con | is_ren ----------------------------------------------------- 1234 | cc | 27-mar-14 | 0 | 0 1234 | cc | 27-jun-14 | 1 | 0 1234 | gui | 27-mar-14 | 0 | 0 1234 | gui | 27-jun-14 | 1 | 0 1234 | gui | 27-sept-14 | 0 | 1 1234 | gui | 27-sept-15 | 0 | 1 1234 | remote | 27-mar-14 | 0 | 0 1234 | remote | 27-jun-14 | 1 | 0 1234 | remote | 27-sept-14 | 0 | 1 2431 | cc | 27-mar-14 | 0 | 0 2431 | cc | 27-jun-14 | 1 | 0
i have query below
select a.reg_id, b.sess_start_dt, case when trunc(a.event_date) - b.sess_start_dt between 0-30 'days 0_30' when trunc(a.event_date) - b.sess_start_dt between 31-60 'days 31-60' tab inner join tab b on a.reg_id = b.reg_id , a.is_ren = 1 union select a.reg_id, b.sess_start_dt, case when trunc(a.event_date) - b.sess_start_dt between 0-30 'days 0_30' when trunc(a.event_date) - b.sess_start_dt between 31-60 'days 31-60' tab inner join tab b on a.reg_id = b.reg_id , a.is_con = 1
tab b contains usage each reg_id there 100's of records.. sample of few
regid | sess_start_dt 1234 | 27-jan-14 1234 | 20-mar-12 1234 | 27-mar-12 1234 | 01-sept-14 1234 | 07-sept-14 1234 | 29-jul-14 1234 | 03-aug-14 1234 | 27-mar-13 1234 | 27-mar-12 1234 | 27-mar-12 1234 | 27-mar-12 1234 | 27-mar-12 1234 | 27-mar-12 1234 | 27-mar-12 2431 | 20-jun-14
the above query needs corrected in way like,
1) if reg_id having @ least 1 is_ren = 1 subscription should considered renewal subscription , needs 30 days , 60 days usage table b is_ren = 1 event_date. (for regid 1234 is_ren query should execute)
2) if multiple is_ren = 1 existing each regid usage needs taken 30 days , 60 days table b min(event_date). in case usage should taken 27-sept-14 instead of 27-sept-15
3) if there no is_ren = 1 , there is_con = 1 it's considered conversion , usage should taken before 60 days converted date (for regid 2431, usage needs 60 days 27-jun-14{this event_date in query})
the o/p should like
regid | event_date | days 0_30 | days 31-60 | code 1234 | 27-sept-14 | 2 | 2 | ren 2431 | 27-jul-14 | 1 | 0 | con
if assumptions in comment correct, may need. notice order by
clause in row_number()
- first rows is_ren = 1
, rows is_ren = 0
, is_con = 1
, other rows, , within each group order event_date
ascending. way, top row (rn = 1
), 1 use in outer query, have is_ren = 1
earliest possible date, or if no is_ren = 1
row is_con = 1
, earliest date, or else earliest date. (in last case, code
null: means there no is_ren = 1
, no is_con = 1
regid
.
not sure why have 27-jul-14
in output regid = 2431
, should 27-jun-14
. also, there no four-letter months in oracle ("sept"). output shows dates using session parameters; if need format dates, use to_date(event_date, .....)
desired date format model. also, since data provided dates (with no time-of-day component), didn't truncate anything; may need to, if real data has time-of-day components.
with table_a ( regid, pkg_desc, event_date, is_con, is_ren ) ( select 1234, 'cc' , to_date ('27-mar-14', 'dd-mon-rr'), 0, 0 dual union select 1234, 'cc' , to_date ('27-jun-14', 'dd-mon-rr'), 1, 0 dual union select 1234, 'gui' , to_date ('27-mar-14', 'dd-mon-rr'), 0, 0 dual union select 1234, 'gui' , to_date ('27-jun-14', 'dd-mon-rr'), 1, 0 dual union select 1234, 'gui' , to_date ('27-sep-14', 'dd-mon-rr'), 0, 1 dual union select 1234, 'gui' , to_date ('27-sep-15', 'dd-mon-rr'), 0, 1 dual union select 1234, 'remote', to_date ('27-mar-14', 'dd-mon-rr'), 0, 0 dual union select 1234, 'remote', to_date ('27-jun-14', 'dd-mon-rr'), 1, 0 dual union select 1234, 'remote', to_date ('27-sep-14', 'dd-mon-rr'), 0, 1 dual union select 2431, 'cc' , to_date ('27-mar-14', 'dd-mon-rr'), 0, 0 dual union select 2431, 'cc' , to_date ('27-jun-14', 'dd-mon-rr'), 1, 0 dual ), table_b ( regid, sess_start_dt ) ( select 1234, to_date ('27-jan-14', 'dd-mon-rr') dual union select 1234, to_date ('20-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('01-sep-14', 'dd-mon-rr') dual union select 1234, to_date ('07-sep-14', 'dd-mon-rr') dual union select 1234, to_date ('29-jul-14', 'dd-mon-rr') dual union select 1234, to_date ('03-aug-14', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-13', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 1234, to_date ('27-mar-12', 'dd-mon-rr') dual union select 2431, to_date ('20-jun-14', 'dd-mon-rr') dual ), prep ( regid, event_date, code, rn ) ( select regid, event_date, case when is_ren = 1 'ren' when is_con = 1 'con' else null end, row_number() on (partition regid order case when is_ren = 1 0 when is_con = 1 1 else 2 end, event_date) table_a ) select p.regid, p.event_date, count(case when b.sess_start_dt between p.event_date - 30 , p.event_date 1 end) days_0_30, count(case when b.sess_start_dt between p.event_date - 60 , p.event_date - 31 1 end) days_31_60, p.code prep p inner join table_b b on p.regid = b.regid rn = 1 group p.regid, p.event_date, p.code ;
output:
regid event_date days_0_30 days_31_60 cod ---------- ------------------- ---------- ---------- --- 1234 2014-09-27 00:00:00 2 2 ren 2431 2014-06-27 00:00:00 1 0 con
Comments
Post a Comment