Home » SQL & PL/SQL » SQL & PL/SQL » Loops (Oracle 11g, XP)
Loops [message #605324] |
Wed, 08 January 2014 13:41 |
rajivn786
Messages: 161 Registered: January 2010
|
Senior Member |
|
|
Hi,
This is the input I have
CREATE TABLE X (MRN VARCHAR2(100), START_DATE DATE, END_DATE DATE, NEXT_DATE DATE);
Insert into BIGDASC.X
(MRN , START_DATE, MOD_END_DATE, NEXT_DATE)
Values
('236046', TO_DATE('11/09/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('04/25/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('04/26/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into BIGDASC.X
(MRN , START_DATE, MOD_END_DATE, NEXT_DATE)
Values
('236046', TO_DATE('04/26/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('05/25/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('05/25/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into BIGDASC.X
(MEDICAL_RECORD_NUMBER, START_DATE, MOD_END_DATE, NEXT_DATE)
Values
('236046', TO_DATE('05/25/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('10/18/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('10/18/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into BIGDASC.X
(MRN , START_DATE, MOD_END_DATE, NEXT_DATE)
Values
('236046', TO_DATE('10/18/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('10/18/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('10/18/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into BIGDASC.X
(MEDICAL_RECORD_NUMBER, START_DATE, MOD_END_DATE, NEXT_DATE)
Values
('236046', TO_DATE('10/18/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into BIGDASC.X
(MRN , START_DATE, MOD_END_DATE, NEXT_DATE)
Values
('236046', TO_DATE('12/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('01/09/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/12/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into BIGDASC.X
(MRN , START_DATE, MOD_END_DATE)
Values
('236046', TO_DATE('12/12/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('01/08/2014 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
COMMIT;
The o/p should be
MRN START_DATE END_DATE
236046 11/9/2010 1/9/2012
236046 12/12/2012 1/8/2014
Procedure to get the output:
1) Loop through all the records for a mrn
2) Get the start date, mod_end_date, next_date for a mrn ordered by start date, mod_end_date for a mrn.
3) Store the 1st record into variables
4) See if next_date - mod_end_date > 1
5) If NOT, preserve the start date.
6) Loop until u find the record where next_date - mod_end_date > 1
7) Once u find that record, store the 1st record start date & mod_end_date of the current record. In this case 11/9/2010 - 1/9/2012...
8) Get the next record where the start date will be the new start date .
9) Repeat the whole process.
The code that can be modified...
declare
V_SAMPLE_NAME VARCHAR2(100);
V_START_DATE DATE;
V_END_DATE DATE;
V_NXT_DATE DATE;
cursor C_ALL_PATIENTS is
Select distinct MRN from x;
cursor C_GENO (p_mrn varchar2) is
Select distinct MRN , to_date(start_date,'mm/dd/yyyy') start_date, mod_end_date, to_date(next_date,'mm/dd/yyyy') next_date from x
where MRN = p_mrn
order by 1,2,3;
TYPE V_TT IS TABLE OF C_GENO%ROWTYPE INDEX BY PLS_INTEGER;
L_TT V_TT;
begin
FOR L1 IN C_ALL_PATIENTS
LOOP
V_SAMPLE_NAME := L1.MRN ;
OPEN C_GENO(L1.MRN );
LOOP
FETCH C_GENO BULK COLLECT INTO L_TT LIMIT 100;
FOR indx IN 1 .. L_TT.COUNT
LOOP
V_START_DATE := L_TT(indx).START_DATE;
V_END_DATE := L_TT(indx).MOD_END_DATE;
V_NXT_DATE := L_TT(indx).NEXT_DATE;
IF L_TT(indx).NEXT_DATE - L_TT(indx).MOD_END_DATE > 1
THEN
-- LOGIC
END IF;
END LOOP;
EXIT WHEN L_TT.COUNT = 0;
END LOOP;
CLOSE C_GENO;
END LOOP;
COMMIT;
END;
Thanks.
[Updated on: Wed, 08 January 2014 13:55] Report message to a moderator
|
|
|
Re: Loops [message #605353 is a reply to message #605324] |
Wed, 08 January 2014 15:36 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
You can scrap all that PL/SQL. This is a simplifed version of start-of-group task:
with t as (
select x.*,
sum(
case
when next_date - end_date > 1 then 1
else 0
end
) over (
partition by mrn
order by start_date,
end_date,
next_date
) grp
from x
)
select mrn,
min(start_date) start_date,
max(end_date) end_date
from t
group by mrn,
grp
order by mrn,
grp
/
MRN START_DAT END_DATE
---------- --------- ---------
236046 09-NOV-10 18-OCT-11
236046 12-DEC-11 08-JAN-14
SCOTT@pdborcl12 >
SY.
|
|
|
Re: Loops [message #605462 is a reply to message #605353] |
Thu, 09 January 2014 10:01 |
rajivn786
Messages: 161 Registered: January 2010
|
Senior Member |
|
|
A slight modification to the code might be needed..Not sure where to modify
The o/p needs to be
MRN START_DAT END_DATE
---------- --------- ---------
236046 09-NOV-10 09-JAN-12 -- the code gives end_date as 18-OCT-11
236046 12-DEC-12 08-JAN-14 -- the code gives start_date as 12-DEC-11
Thanks.
|
|
|
Re: Loops [message #605472 is a reply to message #605462] |
Thu, 09 January 2014 12:36 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
I see, group start AFTER next_date - end_date > 1 is discoverd. Then it is typical start-of-group task:
with t1 as (
select x.*,
case
when lag(next_date - end_date)
over (
partition by mrn
order by start_date,
end_date,
next_date
) > 1 then 1
else 0
end start_of_group
from x
),
t2 as (
select t1.*,
sum(
start_of_group
) over (
partition by mrn
order by start_date,
end_date,
next_date
) grp
from t1
)
select mrn,
min(start_date) start_date,
max(end_date) end_date
from t2
group by mrn,
grp
order by mrn,
grp
/
MRN START_DAT END_DATE
---------- --------- ---------
236046 09-NOV-10 09-JAN-12
236046 12-DEC-12 08-JAN-14
SCOTT@pdborcl12 >
SY.
|
|
|
|
Goto Forum:
Current Time: Fri Apr 26 06:32:30 CDT 2024
|