Hello Folks,
Need your help to build logic for the below requirement.
We have a requirement where we need to fetch the record posted after every 24 hours from the first record time stamp.
details about the requirement:
1) Take the first record for each order_number and corresponding time stamp.
2) take the record posted for the same order number after 24 hours.
3) take the record posted after after 24 hours based on the time stamp from 2nd record.
Below is the sample data set.
RECORD_NUMBERCREATED_DATE5675462015-07-28 10:45:245675462015-07-28 14:13:455675462015-07-28 22:53:195675462015-07-29 08:34:395675462015-07-29 17:13:265675972015-07-26 11:34:295675972015-07-27 10:45:325675972015-07-28 13:12:435675972015-07-29 18:39:51The result should be like below.
RECORD_NUMBERCREATED_DATE5675462015-07-28 10:45:245675462015-07-29 17:13:265675972015-07-26 11:34:295675972015-07-28 13:12:435675972015-07-29 18:39:51The records should be grouped based on record_number.
Regards,
Venkat N.
Window functions are your friends. :-)
SELECT RECORD_NUMBER,MIN(CREATE_DATE) CREATE_DATE FROM ( SELECT *, MIN(TO_DATE) OVER (PARTITION BY RECORD_NUMBER ORDER BY CREATE_DATE DESC) TO_DATE2 FROM ( SELECT *, CASE WHEN DIFF > 24 THEN CREATE_DATE WHEN NEXT_DATE IS NULL THEN '2100-01-01' ELSE NULL END TO_DATE FROM ( SELECT *, SUM(SECONDS_BETWEEN(CREATE_DATE,NEXT_DATE)/3600) OVER (PARTITION BY RECORD_NUMBER ORDER BY CREATE_DATE) DIFF FROM ( SELECT RECORD_NUMBER, CREATE_DATE, LEAD(CREATE_DATE) OVER (PARTITION BY RECORD_NUMBER ORDER BY CREATE_DATE) NEXT_DATE FROM "TEST".TEST_TABLE) GROUP BY RECORD_NUMBER, CREATE_DATE,NEXT_DATE))) GROUP BY RECORD_NUMBER, TO_DATE2 ORDER BY RECORD_NUMBER, CREATE_DATE;
;RECORD_NUMBER;CREATE_DATE 1;567,546 ;Jul 28, 2015 10:45:24.0 AM 2;567,546 ;Jul 29, 2015 5:13:26.0 PM 3;567,597 ;Jul 26, 2015 11:34:29.0 AM 4;567,597 ;Jul 28, 2015 1:12:43.0 PM 5;567,597 ;Jul 29, 2015 6:39:51.0 PM
Please post the create table and insert statements so that we can work with your data.
- Lars
Hello Venkat,
Just an idea from my side..it may need data type casting and with slight adjustment in code it may work..
DROP PROCEDURE <procedure>;
CREATE PROCEDURE <procedure> LANGUAGE SQLSCRIPT AS
BEGIN
DECLARE v_var1 TIMESTAMP;
DECLARE v_temp BIGINT ;
DECLARE c_operator NVARCHAR(1) := '+';
DECLARE c_24hours TIME := '24:00:00';
DECLARE CURSOR c_cursor FOR SELECT record_number , created_date FROM table1 ORDER BY record_number
BEGIN
FOR cur_row as c_cursor DO
v_var1 = cur_row.CREATED_DATE|| c_operator || c_24hours ;
IF cur_row.RECORD_NUMBER <> v_temp THEN
execute immediate 'INSERT INTO SCHEMA.TABLE2 ( RECORD_NUMBER, CREATED_DATE ) -- this should pick the first record for each order_number and corresponding time stamp.
SELECT RECORD_NUMBER , CREATED_DATE FROM TABLE1
WHERE RECORD_NUMBER ='||cur_row.RECORD_NUMBER||'
AND CREATED_DATE = '||cur_row.CREATED_DATE||' ;
execute immediate 'INSERT INTO SCHEMA.TABLE2 ( RECORD_NUMBER, CREATED_DATE ) -- This should pick same record number but posted after after 24 hours based on the time stamp from 2nd record
SELECT RECORD_NUMBER , CREATED_DATE FROM TABLE1
WHERE RECORD_NUMBER ='||cur_row.RECORD_NUMBER||'
AND CREATED_DATE > '||V_VAR1||' ;
v_temp = cur_row.RECORD_NUMBER;
END FOR
END
Thanks
Siva
Message was edited by: Sivakumar Palaniswamy
What about this solution?
select record_number, create_date from ( select tbl.record_number, tbl.create_date, cat.datemin, to_integer((seconds_between(cat.datemin, tbl.create_date)/3600)/24) as days, mod((seconds_between(cat.datemin, tbl.create_date)/3600), 24) as dif from test_table tbl inner join (select distinct record_number, min(CREATE_DATE) as datemin from test_table group by record_number) cat on tbl.record_number = cat.record_number ) where dif = 0 or days >= 1
Add a comment