I have 4 source tables:
CREATE TABLE TABLE1_NAMES (NAMES VARCHAR2(12));
INSERT INTO TABLE1_NAMES VALUES ('JOHN');
INSERT INTO TABLE1_NAMES VALUES ('RYAN');
INSERT INTO TABLE1_NAMES VALUES ('OLAN');
INSERT INTO TABLE1_NAMES VALUES ('TONY');
CREATE TABLE TABLE2_LINES (NAMES VARCHAR2(12), LINE_NO NUMBER, UNITS NUMBER(18,4), CODE VARCHAR2(4));
INSERT INTO TABLE2_LINES VALUES ('JOHN',1,1,'101');
INSERT INTO TABLE2_LINES VALUES ('JOHN',2,1,'202');
INSERT INTO TABLE2_LINES VALUES ('JOHN',3,1,'180');
INSERT INTO TABLE2_LINES VALUES ('JOHN',4,2,'300');
INSERT INTO TABLE2_LINES VALUES ('RYAN',1,2,'180');
INSERT INTO TABLE2_LINES VALUES ('RYAN',2,1,'180');
INSERT INTO TABLE2_LINES VALUES ('RYAN',3,1,'500');
INSERT INTO TABLE2_LINES VALUES ('OLAN',1,1,'301');
INSERT INTO TABLE2_LINES VALUES ('TONY',1,1,'201');
CREATE TABLE TABLE3_DATES (NAMES VARCHAR2(12), FR_DT TIMESTAMP(3), TO_DT TIMESTAMP(3), START_DT TIMESTAMP(3),END_DT TIMESTAMP(3));
INSERT INTO TABLE3_DATES VALUES ('JOHN','01-DEC-22 12.00.00.000000000 AM','05-DEC-22 12.00.00.000000000 AM','03-DEC-22 12.00.00.000000000 AM','09-DEC-22 12.00.00.000000000 AM');
INSERT INTO TABLE3_DATES VALUES ('RYAN','01-DEC-22 12.00.00.000000000 AM','04-DEC-22 12.00.00.000000000 AM','03-DEC-22 12.00.00.000000000 AM','09-DEC-22 12.00.00.000000000 AM');
INSERT INTO TABLE3_DATES VALUES ('OLAN','01-DEC-22 12.00.00.000000000 AM','05-DEC-22 12.00.00.000000000 AM','03-DEC-22 12.00.00.000000000 AM','09-DEC-22 12.00.00.000000000 AM');
INSERT INTO TABLE3_DATES VALUES ('TONY','01-DEC-22 12.00.00.000000000 AM','05-DEC-22 12.00.00.000000000 AM','03-DEC-22 12.00.00.000000000 AM','09-DEC-22 12.00.00.000000000 AM');
CREATE TABLE TABLE4_CODES (CD_NM VARCHAR2(12), B_CODE VARCHAR2(4), E_CODE VARCHAR2(4));
INSERT INTO TABLE4_CODES VALUESS ('CODELIST','100','101');
INSERT INTO TABLE4_CODES VALUESS ('CODELIST','180','180');
INSERT INTO TABLE4_CODES VALUESS ('CODELIST','200','219');
COMMIT;
I have 2 result tables : RESULT1_CALC, RESULT2_FINAL (one table is for calculation of total units per person and other table is the final result table which stores the person name with code)
CREATE TABLE RESULT1_CALC (NAMES VARCHAR2(12), FR_DT TIMESTAMP(3), TO_DT TIMESTAMP(3), START_DT TIMESTAMP(3), END_DT TIMESTAMP(3), TOT_UNITS NUMBER);
CREATE TABLE RESULT2_FINAL (NAMES VARCHAR2(12), EX_CD VARCHAR2(3));
Logic Explanation:
We have TABLE2_LINES
data where we calculate SUM(UNITS)
per person based on CODE
value present in TABLE4_CODES
in such a way that
- If
180
code only is present for a person then calculateSUM(UNITS)
and compare with formulaTO_DT - FR_DT
, if not equal insert record (person name and'ABC'
code) intoRESULT2_FINAL
table - If
180
code is present along with other eligible codes (here eligible code is nothing but code present inTABLE4_CODES
) for a person then calculateSUM(UNITS)
and compare with formulaEND_DT - START_DT
, if not equal insert record (person name and'ABC'
code) intoRESULT2_FINAL
table - If
180
code is not present but other eligible codes are present(here eligible code is nothing but code present inTABLE4_CODES
) for a person then calculateSUM(UNITS)
and compare with formulaEND_DT - START_DT
, if not equal insert record (person name and'ABC'
code) intoRESULT2_FINAL
table
Example:
Case 1: For person
JOHN
, We have eligible codes i.e.101,202, 180
(these codes present inTABLE4_CODES
table) ..It has other eligible codes along with180
soSUM(UNITS)
is3
and this value is compared with formulaTO_DT - FR_DT
i.e. December 5 - December 1 which is 4 (not equal to SUM(UNITS)) so insert into RESULT2_FINAL table.Case 2: For person
RYAN
, We have eligible code i.e.180
only (this code present inTABLE4_CODES
table) ... soSUM(UNITS)
is3
and this value is compared with formulaEND_DT - START_DT
i.e. December 9 - December 3 which is 6 (not equal toSUM(UNITS)
) so insert intoRESULT2_FINAL
table.Case 3: For person
OLAN
, we don't have eligible codes so need to do anything.Case 4: For person
TONY
, we have eligible code 201 but we don't have 180 so (this code present inTABLE4_CODES
table) ... soSUM(UNITS)
is1
and this value is compared with formulaEND_DT - START_DT
i.e. December 9 - December 3 which is 6 (not equal toSUM(UNITS)
) so insert intoRESULT2_FINAL
table.
But in SQL query which I have mentioned below, it is not inserting person RYAN
and also TONY
records into RESULT2_FINAL
table as I am not sure how to write query to differ the above 2 cases with calculation to get expected result.
INSERT INTO RESULT1_CALC
(
SELECT T1.NAMES, T3.FR_DT, T3.TO_DT, T3.START_DT, T3.END_DT, RES.TOT_UNITS
FROM TABLE1_NAMES T1
JOIN (
SELECT T2.NAMES, SUM(T2.UNITS), TOT_UNITS
FROM TABLE2_LINES T2
JOIN TABLE4_CODES T4
ON T4.CD_NM = 'CODELIST'
AND T2.CODE BETWEEN T4.B_CODE AND T4.E_CODE
GROUP BY T2.NAMES
) RES
ON T1.NAMES = RES.NAMES
JOIN TABLE3_DATES T3
ON T1.NAMES = T3.NAMES
);
COMMIT;
INSERT INTO RESULT2_FINAL
(
SELECT DISTINCT R1.NAMES, 'ABC' EX_CD
FROM RESULT1_CALC R1
WHERE R1.TOT_UNITS <> (EXTRACT(DAY FROM TO_DT - FR_DT))
);
COMMIT;
Output at the end:
RESULT2_FINAL
table should be populated with the help ofRESULT1_CALC
table.
NAMES | EX_CD |
---|---|
JOHN | ABC |
RYAN | ABC |
TONY | ABC |
CodePudding user response:
You don't need RESULT1_CALC
and can just insert the rows directly using the source tables into the final table:
INSERT INTO RESULT2_FINAL (names, ex_cd)
SELECT l.names, 'ABC'
FROM (
SELECT names,
SUM(units) AS total_units,
COUNT(CASE WHEN l.code = '180' THEN 1 END) AS has180,
COUNT(CASE WHEN l.code = '180' THEN NULL ELSE 1 END) AS hasOther
FROM TABLE4_CODES c
INNER JOIN TABLE2_LINES l
ON TO_NUMBER(l.code) BETWEEN TO_NUMBER(c.b_code) AND TO_NUMBER(c.e_code)
WHERE c.cd_nm = 'CODELIST'
GROUP BY names
) l
INNER JOIN TABLE3_DATES d
ON l.names = d.names
WHERE ( l.has180 > 0 AND l.hasOther = 0
AND NUMTODSINTERVAL(l.total_units, 'DAY') = d.to_dt - d.fr_dt
)
OR ( l.has180 > 0 AND l.hasOther > 0
AND NUMTODSINTERVAL(l.total_units, 'DAY') != d.end_dt - d.start_dt
);
Which, for the sample data, inserts the values:
NAMES | EX_CD |
---|---|
JOHN | ABC |
RYAN | ABC |