count from current row to last row - oracle

I have a requirement to pull the data in the below fashion.
progress_CMC_status progress_cmc_status_numbers cmc_status_numbers
Mature Draft 2 5
Review 0 3
Final Draft 0 3
Final Comment 0 3
Final Document 2 3
Archived Document 1 1
but i am getting output in different
progress_CMC_status progress_cmc_status_numbers cmc_status_numbers
Mature Draft 2 5
Review 0 0
Final Draft 0 0
Final Comment 0 0
Final Document 2 3
Archived Document 1 1
Tried the below code:
WITH sta AS
(SELECT 'Mature' "status1"
FROM DUAL
UNION
SELECT 'Review'
FROM DUAL
UNION
SELECT 'Final Draft'
FROM DUAL
UNION
SELECT 'Final Comment'
FROM DUAL
UNION
SELECT 'Final Document'
FROM DUAL
UNION
SELECT 'Archived'
FROM DUAL)
SELECT DECODE ("stat",
'Mature', 'Mature Draft',
'Review', 'Review',
'Final Draft', 'Final Draft',
'Final Comment', 'Final Comment',
'Final Document', 'Final Document',
'Archived', 'Archived Document'
) AS "progress_CMC_status",
NVL
(TO_CHAR ("progress_cmc_status_numbers"),
0
) AS "progress_cmc_status_numbers",
NVL (TO_CHAR ("cmc_status_numbers"), 0) AS "cmc_status_numbers"
FROM (SELECT "status1" AS "stat",
NVL
(TO_CHAR (NULL),
"progress_cmc_status_numbers"
) AS "progress_cmc_status_numbers",
NVL (TO_CHAR (NULL),
"cmc_status_numbers"
) AS "cmc_status_numbers"
FROM sta
LEFT JOIN
(SELECT VALUE AS "progress_CMC_status",
COUNT (*) AS "progress_cmc_status_numbers",
SUM (COUNT (*)) OVER (ORDER BY DECODE
(VALUE,
'Mature', 0,
'Review', 1,
'Final Draft', 2,
'Final Comment', 3,
'Final Document', 4,
'Archived', 5,
6
) DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS "cmc_status_numbers"
FROM ATTRIBUTES
WHERE attribute_type_id IN (
SELECT attribute_type_id
FROM attribute_types
WHERE name_display_code =
'RD')
AND VALUE IN
('Mature', 'Review', 'Final Draft',
'Final Comment', 'Final Document', 'Archived')
AND object_id IN (SELECT obj_id
FROM docs)
GROUP BY VALUE) a1 ON sta."status1" =
a1."progress_CMC_status"
)
ORDER BY DECODE ("progress_CMC_status",
'Mature Draft', 0,
'Review', 1,
'Final Draft', 2,
'Final Comment', 3,
'Final Document', 4,
'Archived Document', 5,
6
)
sample data
CREATE TABLE ATTRIBUTES
(
object_id NUMBER(4),
attribute_type_id NUMBER(4),
name_display_code VARCHAR2(5),
VALUE VARCHAR2(25)
);
begin
insert into attributes values (101,201,'RMD','A100');
insert into attributes values (102,201,'RMD','A200');
insert into attributes values (103,201,'RMD','A300');
insert into attributes values (104,200,'RD','Mature');
insert into attributes values (105,200,'RD','Mature');
insert into attributes values (106,200,'RD','Mature');
insert into attributes values (107,200,'RD','Mature');
insert into attributes values (108,200,'RD','Mature');
insert into attributes values (109,200,'RD','Archived');
insert into attributes values (110,200,'RD','Archived');
insert into attributes values (111,200,'RD','Archived');
insert into attributes values (112,200,'RD','Archived');
insert into attributes values (113,200,'RD','Mature');
insert into attributes values (114,200,'RD','Mature');
insert into attributes values (115,200,'RD','Mature');
insert into attributes values (116,200,'RD','Mature');
insert into attributes values (117,200,'RD','Final Document');
insert into attributes values (118,200,'RD','Final Document');
insert into attributes values (119,201,'RMD','A400');
insert into attributes values (120,201,'RMD','A500');
end;
/
CREATE TABLE docs
(
obj_id NUMBER(4)
);
BEGIN
INSERT INTO docs
VALUES (100);
INSERT INTO docs
VALUES (104);
INSERT INTO docs
VALUES (109);
INSERT INTO docs
VALUES (117);
INSERT INTO docs
VALUES (118);
INSERT INTO docs
VALUES (119);
INSERT INTO docs
VALUES (120);
END;
/
CREATE TABLE attribute_types
(
attribute_type_id NUMBER(4),
name_display_code VARCHAR2(5)
);
INSERT INTO attribute_types
VALUES (200, 'RD');
INSERT INTO attribute_types
VALUES (201, 'RMD');

WITH sta AS
(SELECT 'Mature' "status1" FROM DUAL UNION
SELECT 'Review' FROM DUAL UNION
SELECT 'Final Draft' FROM DUAL UNION
SELECT 'Final Comment' FROM DUAL UNION
SELECT 'Final Document' FROM DUAL UNION
SELECT 'Archived' FROM DUAL)
SELECT
DECODE ("stat",
'Mature', 'Mature Draft',
'Review', 'Review',
'Final Draft', 'Final Draft',
'Final Comment', 'Final Comment',
'Final Document', 'Final Document',
'Archived', 'Archived Document'
) AS "progress_CMC_status",
NVL("progress_cmc_status_numbers", 0) AS "progress_cmc_status_numbers",
SUM (NVL("progress_cmc_status_numbers", 0)) OVER (ORDER BY
-DECODE ("stat",
'Mature', 0,
'Review', 1,
'Final Draft', 2,
'Final Comment', 3,
'Final Document', 4,
'Archived', 5,
6)
) AS "cmc_status_numbers"
FROM
(
SELECT
"status1" AS "stat",
"progress_cmc_status_numbers"
FROM
sta
LEFT JOIN (
SELECT
VALUE AS "progress_CMC_status",
COUNT (*) AS "progress_cmc_status_numbers"
FROM ATTRIBUTES
WHERE
attribute_type_id IN (
SELECT attribute_type_id
FROM attribute_types
WHERE name_display_code = 'RD'
)
AND VALUE IN ('Mature', 'Review', 'Final Draft',
'Final Comment', 'Final Document', 'Archived')
AND object_id IN (SELECT obj_id FROM docs)
GROUP BY VALUE
) a1 ON sta."status1" = a1."progress_CMC_status"
)
ORDER BY DECODE ("progress_CMC_status",
'Mature Draft', 0,
'Review', 1,
'Final Draft', 2,
'Final Comment', 3,
'Final Document', 4,
'Archived Document', 5,
6)
fiddle

Related

group orders based on crossing date ranges

I need to group order together with crossing their date ranges only
scenario A.
order 1, 1.3.2020-30.6.2020
order 2, 1.5.2020-31.8.2020
order 3, 31.7.2020-31.10.2020
order 4, 31.7.2020-31.12.2020
so the output should be
order 1, order 2
order 2, order 3, order 4
order1,3,4 are not grouped because their ranges don't cross at all
scenario B.
same as above plus another order
order 5, 1.1.2020-31.12.2020
so output will be
order 1, order 2, order 5
order 2, order 3, order 4, order 5
I tried Self Join to check which start date falls in that range.
so in the range of order 1 falls only the start date of order 2 -> we have one group
then in the range of order 2 fall both start dates of order 3 and 4 -> we have second group
but then for order 3 falls start date of order 4 and opposite -> that will give another 2 groups but they are invalid because order 2 is crossing their date ranges as well and shoul be included as well and becuase there will be 3 douplicates we should display it just once as in the desired output but this approach will fail.
Thanks
the result of MATCH_RECOGNIZE solution is incorrent because order 5 should be in both groups
I use some analitycal functions to solve this:
-- create table
Create table cross_dates (order_id number, start_date date , end_date date);
-- insert dates
insert into cross_dates values( 1, to_date('01.03.2020', 'dd.mm.yyyy'), to_date('30.06.2020', 'dd.mm.yyyy'));
insert into cross_dates values( 2, to_date('01.05.2020', 'dd.mm.yyyy'), to_date( '31.08.2020', 'dd.mm.yyyy'));
insert into cross_dates values( 3, to_date('31.07.2020', 'dd.mm.yyyy'), to_date( '31.08.2020', 'dd.mm.yyyy'));
insert into cross_dates values( 4, to_date('31.07.2020', 'dd.mm.yyyy'), to_date( '31.10.2020', 'dd.mm.yyyy'));
insert into cross_dates values( 5, to_date('01.01.2020', 'dd.mm.yyyy'), to_date( '31.12.2020', 'dd.mm.yyyy'));
-- SQL
select 'Order '|| min_order_id ||': ', listagg( order_id, ',') within group (order by order_id) list
from (
select distinct min_order_id, order_id from (
with dates (cur_date, end_date, order_id, start_date) as (
select start_date, end_date, order_id, start_date
from cross_Dates
union all
select cur_date + 1, end_date, order_id,start_date
from dates
where cur_date < end_date )
select d.order_id,
min(d.order_id) over(partition by greatest(d.start_date, cd.start_date)) min_order_id
from dates d, cross_Dates cd
where d.cur_date between cd.start_date and cd.end_date ))
group by min_order_id
having count(*) > 1;
Result:
Order 1: 1,2,5
Order 2: 2,3,4,5
-- add new column and update old records
alter table cross_dates add (item varchar2(1));
update cross_dates set item = 'A';
-- insert new records B
insert into cross_dates values( 1, to_date('01.01.2020', 'dd.mm.yyyy'), to_date( '30.06.2020', 'dd.mm.yyyy'), 'B');
insert into cross_dates values( 1, to_date('01.07.2020', 'dd.mm.yyyy'), to_date( '31.12.2020', 'dd.mm.yyyy'), 'B');
My assumption:
A and B are separate orders, not going in same groups even when crossing
order 1 B - has two records as a continuations - in my understanding counts like one order : order 1 B 01.01.2020 - 21.12.2020
If my assumption are correct the SQL could look like this:
select distinct min_order_id, order_id, item from (
with dates (cur_date, end_date, order_id, start_date, item) as (
select start_date, end_date, order_id, start_date, item
from cross_Dates
union all
select cur_date + 1, end_date, order_id,start_date, item
from dates
where cur_date < end_date )
select d.order_id, d.item,
min(d.order_id) over(partition by greatest(d.start_date, cd.start_date),d.item) min_order_id
from dates d, cross_Dates cd
where d.cur_date between cd.start_date and cd.end_date and d.item = cd.item )
order by item, min_order_id;
Result:
MIN_ORDER_ID ORDER_ID I
1 1 A
1 2 A
1 5 A
2 2 A
2 3 A
2 4 A
2 5 A
5 5 A
1 1 B
If my assumption are not ok please provide me what result should look like i this case.
:)
You can use MATCH_RECOGNIZE to find groups where the next value's start date is before, or equal to, the end date of all the previous values in the group. Then you can aggregate and exclude groups that would be entirely contained in another group:
WITH groups ( id, ids, start_date, end_date ) AS (
SELECT id,
LISTAGG( grp_id, ',' ) WITHIN GROUP ( ORDER BY start_date ),
MIN( start_date ),
MIN( end_date )
FROM (
SELECT t.id,
x.id AS grp_id,
x.start_date,
x.end_date
FROM table_name t
INNER JOIN table_name x
ON (
x.start_date >= t.start_date
AND x.start_date <= t.end_date
)
)
MATCH_RECOGNIZE (
PARTITION BY id
ORDER BY start_date
MEASURES
MATCH_NUMBER() AS mno
ALL ROWS PER MATCH
PATTERN ( FIRST_ROW GROUPED_ROWS* )
DEFINE GROUPED_ROWS AS (
GROUPED_ROWS.start_date <= MIN( end_date )
)
)
WHERE mno = 1
GROUP BY id
)
SELECT id,
ids
FROM groups g
WHERE NOT EXISTS (
SELECT 1
FROM groups x
WHERE g.ID <> x.ID
AND x.start_date <= g.start_date
AND g.end_date <= x.end_date
)
Which for the sample data:
CREATE TABLE table_name ( id, start_date, end_date ) AS
SELECT 'order 1', DATE '2020-03-01', DATE '2020-06-30' FROM DUAL UNION ALL
SELECT 'order 2', DATE '2020-05-01', DATE '2020-08-31' FROM DUAL UNION ALL
SELECT 'order 3', DATE '2020-07-31', DATE '2020-10-31' FROM DUAL UNION ALL
SELECT 'order 4', DATE '2020-07-31', DATE '2020-12-31' FROM DUAL;
Outputs:
ID | IDS
:------ | :----------------------
order 2 | order 2,order 3,order 4
order 1 | order 1,order 2
I you then:
INSERT INTO table_name ( id, start_date, end_date )
VALUES ( 'order 5', DATE '2020-01-01', DATE '2020-12-31' );
The output would be:
ID | IDS
:------ | :----------------------
order 2 | order 2,order 3,order 4
order 5 | order 5,order 1,order 2
db<>fiddle here

Create View but get Warning: compiled but with compilation error in oracle

When i create a view I am getting this warning in Toad:
Warning: compiled but with compilation error in oracle
This is my script:
CREATE OR REPLACE FORCE VIEW APPS.KMI_OKP_TRACK_V
(
NO_OKP,
LINE,
FBD_PSD,
FBD_ASD,
FBD_PCD,
FBD_ACD,
FBD_DD,
FBD_BCD,
MIX_PSD,
MIX_ASD,
MIX_PCD,
MIX_ACD,
MIX_DD,
MIX_BCD,
BPR_PSD,
BPR_ASD,
BPR_PCD,
BPR_ACD,
BPR_DD,
BPR_BCD,
BLD_PSD,
BLD_ASD,
BLD_PCD,
BLD_ACD,
BLD_DD,
BLD_BCD,
CAN_PSD,
CAN_ASD,
CAN_PCD,
CAN_ACD,
CAN_DD,
CAN_BCD,
BAG_PSD,
BAG_ASD,
BAG_PCD,
BAG_ACD,
BAG_DD,
BAG_BCD,
DPG_PSD,
DPG_ASD,
DPG_PCD,
DPG_ACD,
DPG_DD,
DPG_BCD,
SAC_PSD,
SAC_ASD,
SAC_PCD,
SAC_ACD,
SAC_DD,
SAC_BCD,
BPE_PSD,
BPE_ASD,
BPE_PCD,
BPE_ACD,
BPE_DD,
BPE_BCD
)
AS
SELECT DISTINCT XX.NO_OKP,
XX.LINE --,XX.CREATION_DATE
,
FBD.FBD_PSD,
FBD.FBD_ASD,
FBD.FBD_PCD,
FBD.FBD_ACD,
FBD.FBD_DD,
FBD.FBD_BCD,
MIX.MIX_PSD,
MIX.MIX_ASD,
MIX.MIX_PCD,
MIX.MIX_ACD,
MIX.MIX_DD,
MIX.MIX_BCD,
BPR.BPR_PSD,
BPR.BPR_ASD,
BPR.BPR_PCD,
BPR.BPR_ACD,
BPR.BPR_DD,
BPR.BPR_BCD,
BLD.BLD_PSD,
BLD.BLD_ASD,
BLD.BLD_PCD,
BLD.BLD_ACD,
BLD.BLD_DD,
BLD.BLD_BCD,
CAN.CAN_PSD,
CAN.CAN_ASD,
CAN.CAN_PCD,
CAN.CAN_ACD,
CAN.CAN_DD,
CAN.CAN_BCD,
BAG.BAG_PSD,
BAG.BAG_ASD,
BAG.BAG_PCD,
BAG.BAG_ACD,
BAG.BAG_DD,
BAG.BAG_BCD,
DPG.DPG_PSD,
DPG.DPG_ASD,
DPG.DPG_PCD,
DPG.DPG_ACD,
DPG.DPG_DD,
DPG.DPG_BCD,
SAC.SAC_PSD,
SAC.SAC_ASD,
SAC.SAC_PCD,
SAC.SAC_ACD,
SAC.SAC_DD,
SAC.SAC_BCD,
BPE.BPE_PSD,
BPE.BPE_ASD,
BPE.BPE_PCD,
BPE.BPE_ACD,
BPE.BPE_DD,
BPE.BPE_BCD
FROM ( SELECT DISTINCT
RTRIM (
SUBSTR (BATCH_NO, 4, 4),
'A'
)
no_okp,
ATTRIBUTE1 LINE --,CREATION_DATE
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date,
'MM/DD/YYYY') IN
(TO_CHAR (
SYSDATE - 7,
'MM/DD/YYYY'
),
TO_CHAR (
SYSDATE - 8,
'MM/DD/YYYY'
))
ORDER BY CREATION_DATE DESC) XX
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (
SUBSTR (BATCH_NO, 4, 4),
'A'
)
no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE FBD_PSD,
ACTUAL_START_DATE FBD_ASD,
PLAN_CMPLT_DATE FBD_PCD,
ACTUAL_CMPLT_DATE FBD_ACD,
DUE_DATE FBD_DD,
BATCH_CLOSE_DATE FBD_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date,
'MM/DD/YYYY') IN
(TO_CHAR (
SYSDATE - 7,
'MM/DD/YYYY'
),
TO_CHAR (
SYSDATE - 8,
'MM/DD/YYYY'
))
AND attribute1 = 'FAT BLEND'
ORDER BY CREATION_DATE DESC) FBD
ON XX.NO_OKP = FBD.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4),
'A')
no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE MIX_PSD,
ACTUAL_START_DATE MIX_ASD,
PLAN_CMPLT_DATE MIX_PCD,
ACTUAL_CMPLT_DATE MIX_ACD,
DUE_DATE MIX_DD,
BATCH_CLOSE_DATE MIX_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date,
'MM/DD/YYYY') IN
(TO_CHAR (
SYSDATE - 7,
'MM/DD/YYYY'
),
TO_CHAR (
SYSDATE - 8,
'MM/DD/YYYY'
))
AND attribute1 = 'MIX'
ORDER BY CREATION_DATE DESC) MIX
ON XX.NO_OKP = MIX.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4),
'A')
no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE BPR_PSD,
ACTUAL_START_DATE BPR_ASD,
PLAN_CMPLT_DATE BPR_PCD,
ACTUAL_CMPLT_DATE BPR_ACD,
DUE_DATE BPR_DD,
BATCH_CLOSE_DATE BPR_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date,
'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7,
'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8,
'MM/DD/YYYY'))
AND attribute1 = 'BASE POWDER'
ORDER BY CREATION_DATE DESC) BPR
ON XX.NO_OKP = BPR.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4), 'A')
no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE BLD_PSD,
ACTUAL_START_DATE BLD_ASD,
PLAN_CMPLT_DATE BLD_PCD,
ACTUAL_CMPLT_DATE BLD_ACD,
DUE_DATE BLD_DD,
BATCH_CLOSE_DATE BLD_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date,
'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7,
'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8,
'MM/DD/YYYY'))
AND attribute1 = 'BLEND'
ORDER BY CREATION_DATE DESC) BLD
ON XX.NO_OKP = BLD.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4), 'A')
no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE CAN_PSD,
ACTUAL_START_DATE CAN_ASD,
PLAN_CMPLT_DATE CAN_PCD,
ACTUAL_CMPLT_DATE CAN_ACD,
DUE_DATE CAN_DD,
BATCH_CLOSE_DATE CAN_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date,
'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7,
'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8,
'MM/DD/YYYY'))
AND attribute1 = 'CANNING'
ORDER BY CREATION_DATE DESC) CAN
ON XX.NO_OKP = CAN.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4), 'A') no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE BAG_PSD,
ACTUAL_START_DATE BAG_ASD,
PLAN_CMPLT_DATE BAG_PCD,
ACTUAL_CMPLT_DATE BAG_ACD,
DUE_DATE BAG_DD,
BATCH_CLOSE_DATE BAG_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date, 'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7,
'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8,
'MM/DD/YYYY'))
AND attribute1 = 'BAG'
ORDER BY CREATION_DATE DESC) BAG
ON XX.NO_OKP = BAG.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4), 'A') no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE DPG_PSD,
ACTUAL_START_DATE DPG_ASD,
PLAN_CMPLT_DATE DPG_PCD,
ACTUAL_CMPLT_DATE DPG_ACD,
DUE_DATE DPG_DD,
BATCH_CLOSE_DATE DPG_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date, 'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7, 'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8, 'MM/DD/YYYY'))
AND attribute1 = 'DUMPING'
ORDER BY CREATION_DATE DESC) DPG
ON XX.NO_OKP = DPG.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4), 'A') no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE SAC_PSD,
ACTUAL_START_DATE SAC_ASD,
PLAN_CMPLT_DATE SAC_PCD,
ACTUAL_CMPLT_DATE SAC_ACD,
DUE_DATE SAC_DD,
BATCH_CLOSE_DATE SAC_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date, 'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7, 'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8, 'MM/DD/YYYY'))
AND attribute1 IN ('SACHET D', 'SACHET A')
ORDER BY CREATION_DATE DESC) SAC
ON XX.NO_OKP = SAC.NO_OKP
LEFT OUTER JOIN
( SELECT DISTINCT
RTRIM (SUBSTR (BATCH_NO, 4, 4), 'A') no_okp,
attribute1 Line,
DECODE (batch_status,
'1', 'Inspect',
'2', 'Release',
'3', 'Complete',
'Close')
Batch_status,
CREATION_DATE,
PLAN_START_DATE BPE_PSD,
ACTUAL_START_DATE BPE_ASD,
PLAN_CMPLT_DATE BPE_PCD,
ACTUAL_CMPLT_DATE BPE_ACD,
DUE_DATE BPE_DD,
BATCH_CLOSE_DATE BPE_BCD
FROM GME_BATCH_HEADER
WHERE ORGANIZATION_ID = 84
AND TO_CHAR (creation_date, 'MM/DD/YYYY') IN
(TO_CHAR (SYSDATE - 7, 'MM/DD/YYYY'),
TO_CHAR (SYSDATE - 8, 'MM/DD/YYYY'))
AND attribute1 = 'SACHET E'
ORDER BY CREATION_DATE DESC) BPE
ON XX.NO_OKP = BPE.NO_OKP
ORDER BY xx.no_okp ASC;
Where is the fault ?how to get the specific error code ?
To find the specific errors, either:
Test it without the force keyword.
Test it without the create view ... as part, i.e. test the select part on its own.
In SQL*Plus or compatible tools, execute the following command while connected as the APPS user: show errors view kmi_okp_track_v (or include the schema if executing from a DBA account)
Query user_errors while connected as the APPS user (or dba_errors if executing from a DBA account).
Example:
SQL> create or replace force view demo_view as
2 select nosuchcolumn from dual;
Warning: View created with compilation errors.
Test without the force keyword:
SQL> create or replace view demo_view as
2 select nosuchcolumn from dual;
select nosuchcolumn from dual
*
ERROR at line 2:
ORA-00904: "NOSUCHCOLUMN": invalid identifier
Testing the select statement on its own:
SQL> select nosuchcolumn from dual;
select nosuchcolumn from dual
*
ERROR at line 1:
ORA-00904: "NOSUCHCOLUMN": invalid identifier
Using show errors:
SQL> show errors view demo_view
Errors for VIEW DEMO_VIEW:
LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 ORA-00904: "NOSUCHCOLUMN": invalid identifier
Querying user_errors view:
SQL> col text format a70
SQL> select text from user_errors e
2 where e.name = 'DEMO_VIEW'
3 order by e.sequence;
TEXT
----------------------------------------------------------------------
ORA-00904: "NOSUCHCOLUMN": invalid identifier
For deployment scripts, I would include the force keyword and show errors at the end.
There's no problem with your syntax, and you may create this view in your current user, provided the schema prefix APPS. is removed from CREATE OR REPLACE FORCE VIEW APPS.KMI_OKP_TRACK_V.
If you need to create this view from your current schema, you need more prefixes for GME_BATCH_HEADER and the creation privilege should be granted for APPS schema.
As Barbaros said your query look good.
But here a problem i ran into - perhaps it's your problem, too.
-- This will work
CREATE OR REPLACE FORCE VIEW MySchema.MyView
(
MyColumn
)
AS
SELECT "MyColumn" FROM myTable;
-- This won't - because of the delimiter (';') in our variable myquery
DECLARE
myquery VARCHAR2(2000) :=
'CREATE OR REPLACE FORCE VIEW MySchema.MyView
(
MyColumn
)
AS
SELECT "MyColumn" FROM myTable;'
;
BEGIN
EXECUTE IMMEDIATE myquery;
END;
If you EXECUTE IMMEDIATE a query, it must not have a delimiter - neither ; nor /. This is not allowed because you always have to run a single statement, not a list of statement seperated by a delimiter.
The correct version is this:
-- This won't - because of the delimiter (';') in our variable myquery
DECLARE
myquery VARCHAR2(2000) :=
'CREATE OR REPLACE FORCE VIEW MySchema.MyView
(
MyColumn
)
AS
SELECT "MyColumn" FROM myTable' -- no ';' here
;
BEGIN
EXECUTE IMMEDIATE myquery;
END;
Fun-fact: Your View will be created and will work after a recompile.

Correlated SQL Query using With Clause

I am trying to modify below query :
SELECT START_END.*, START_END.LOAD_TIME_END - START_END.LOAD_TIME_START
FROM
(
SELECT START.JOB_ID, START.LOAD_TIME_START, END.LOAD_TIME_END
FROM
(
SELECT JOB_ID,LOAD_TIME AS LOAD_TIME_START
FROM JOB_CTRL_RECON JCR
INNER JOIN
(
SELECT JOB_ID AS JOB_ID_S, MAX(RECON_ID) AS S_MAX_RECON_ID
FROM job_ctrl_recon
where job_id in ('1','2')
and count_type = 'Source'
GROUP BY JOB_ID
) SMAX
ON JCR.JOB_ID = SMAX.S_MAX_RECON_ID
AND JCR.RECON_ID = SMAX.RECON_ID
) START
INNER JOIN
(
SELECT JOB_ID,LOAD_TIME AS LOAD_TIME_END FROM JOB_CTRL_RECON JCR INNER JOIN
(
SELECT JOB_ID AS JOB_ID_T, MAX(RECON_ID) AS T_MAX_RECON_ID
FROM job_ctrl_recon
where job_id in ('1','2')
and count_type = 'Target'
GROUP BY JOB_ID
) TMAX
ON JCR.JOB_ID = TMAX.T_MAX_RECON_ID
AND JCR.RECON_ID = TMAX.RECON_ID
) END
ON START.JOB_ID = END.JOB_ID
) START_END
to a query using with clause as below :
How can i eliminate the multiple use of where job_id in ('1','2') using with clause something like below :
WITH A AS
(
SELECT JOB_ID FROM JOB_CTRL_RECON WHERE JOB_ID IN ('60','67')
)
SELECT START_END.*, START_END.LOAD_TIME_END - START_END.LOAD_TIME_START
FROM
(
SELECT START.JOB_ID, START.LOAD_TIME_START, END.LOAD_TIME_END
FROM
(
SELECT JOB_ID,LOAD_TIME AS LOAD_TIME_START
FROM JOB_CTRL_RECON JCR
INNER JOIN
(
SELECT JOB_ID AS JOB_ID_S, MAX(RECON_ID) AS S_MAX_RECON_ID
FROM job_ctrl_recon
where job_id in (????)
and count_type = 'Source'
GROUP BY JOB_ID
) SMAX
ON JCR.JOB_ID = SMAX.S_MAX_RECON_ID
AND JCR.RECON_ID = SMAX.RECON_ID
) START
INNER JOIN
(
SELECT JOB_ID,LOAD_TIME AS LOAD_TIME_END
FROM JOB_CTRL_RECON JCR
INNER JOIN
(
SELECT JOB_ID AS JOB_ID_T, MAX(RECON_ID) AS T_MAX_RECON_ID
FROM job_ctrl_recon
where job_id in (????)
and count_type = 'Target'
GROUP BY JOB_ID
) TMAX
ON JCR.JOB_ID = TMAX.T_MAX_RECON_ID
AND JCR.RECON_ID = TMAX.RECON_ID
) END
ON START.JOB_ID = END.JOB_ID
) START_END, A
WHERE START_END.JOB_ID = A.JOB_ID
Instead of WITH, you may be able to simplify the code using a KEEP with an analytic function. The code is a bit weird at first, but it lets you only specify the JOB_ID once and it only has to read from the table once.
--Load time start and end for each JOB_ID, based on the latest RECON_ID.
select
job_id,
max(load_time_start) load_time_start,
max(load_time_end) load_time_end,
max(load_time_end) - max(load_time_start) diff
from
(
--First and last load time for each set of rows, with some debug data.
select job_id, count_type, recon_id, load_time
,last_value(case when count_type = 'Source' then load_time else null end)
over (
partition by job_id, count_type
order by recon_id
rows between unbounded preceding and unbounded following
) load_time_start
,last_value(case when count_type = 'Target' then load_time else null end)
over (
partition by job_id, count_type
order by recon_id
rows between unbounded preceding and unbounded following
) load_time_end
from job_ctrl_recon
where job_id in (1,2)
)
group by job_id
order by job_id;
For this table and data:
create table job_ctrl_recon(job_id number, recon_id number, count_type varchar2(100), load_time date);
alter session set nls_date_format = 'DD-Mon-RR';
insert into job_ctrl_recon
select 1, 400, 'Source', '24-Feb-18' from dual union all
select 1, 40, 'Source', '23-Feb-18' from dual union all
select 1, 89, 'Target', '25-Feb-18' from dual union all
select 1, 8, 'Target', '25-Feb-18' from dual union all
select 2, 700, 'Source', '24-Feb-18' from dual union all
select 2, 8, 'Source', '23-Feb-18' from dual union all
select 2, 567, 'Target', '25-Feb-18' from dual union all
select 2, 45, 'Target', '25-Feb-18' from dual union all
select 2, 678, 'Target', '25-Feb-18' from dual;
commit;
These are the results:
JOB_ID LOAD_TIME_START LOAD_TIME_END DIFF
------ --------------- ------------- ----
1 2018-02-24 2018-02-25 1
2 2018-02-24 2018-02-25 1
Try this one. Hope it helps. Thanks.
old: where job_id in (????)
new: where job_id in (select JOB_ID from A)

Passing a delimited string in the NOT IN clause

The below SQL conceptually replicates the problem I'm trying to solve. Despite passing a NOT IN clause all three records are returned.
SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL
UNION
SELECT 'JOHN' AS VALUE FROM DUAL
UNION
SELECT 'BOB' AS VALUE FROM DUAL
) WHERE VALUE NOT IN (SELECT 'BOB,JOHN' FROM DUAL);
I have a table that holds a delimited string that I want to use as the criteria to exclude records from the dataset. However, the problem I have is that the returned string is not broken down into its delimited items. I want the above to translate to:
SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL
UNION
SELECT 'JOHN' AS VALUE FROM DUAL
UNION
SELECT 'BOB' AS VALUE FROM DUAL
) WHERE VALUE NOT IN ('BOB','JOHN');
You can use regexp_substr for that problem:
SELECT * FROM (
SELECT 'JACK' AS VALUE FROM DUAL
UNION
SELECT 'JOHN' AS VALUE FROM DUAL
UNION
SELECT 'BOB' AS VALUE FROM DUAL
)
WHERE VALUE NOT IN (SELECT regexp_substr('BOB,JOHN','[^,]+', 1, LEVEL) FROM dual CONNECT BY regexp_substr('BOB,JOHN', '[^,]+', 1, LEVEL) IS NOT NULL)
'BOB,JOHN' is not a list of two string values it is one string value that just happens to contain a comma in the string and:
'JACK' = 'BOB,JOHN'
'JOHN' = 'BOB,JOHN'
'BOB' = 'BOB,JOHN'
Are all false so your query will return all rows as matched by the NOT IN filter.
You can surround your values and list with the delimiter characters and test whether the value is not a sub-string of the list like this:
SELECT *
FROM (
SELECT 'JACK' AS VALUE FROM DUAL UNION ALL
SELECT 'JOHN' AS VALUE FROM DUAL UNION ALL
SELECT 'BOB' AS VALUE FROM DUAL
)
WHERE INSTR( ',' || 'BOB,JOHN' || ',', ',' || value || ',' ) = 0
Or you can use a user-defined collection:
CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(20);
Then use the MEMBER OF operator to test whether a value is a member of the collection:
SELECT *
FROM (
SELECT 'JACK' AS VALUE FROM DUAL UNION ALL
SELECT 'JOHN' AS VALUE FROM DUAL UNION ALL
SELECT 'BOB' AS VALUE FROM DUAL
)
WHERE VALUE NOT MEMBER OF StringList( 'BOB', 'JOHN' );

SQL Select related tables into new columns

I have a table in SQL that has 3 columns:
CategoryName
WarnInterval
ErrorInterval
And then I have another table which has 4 columns:
CategoryName
GroupName
IncludedExcluded
Match
Each row in this table has 2 unique records based on CategoryName, GroupName and IncludedExcluded. For example, as json it looks like this:
{
categoryName: 'Folders',
groupName: 'Products',
includeExcluded: 'E',
match: 'SomeProduct'
}, {
categoryName: 'Folders',
groupName: 'Products',
includeExcluded: 'I',
match: 'SomeOtherProduct'
}
There are 3 Groups (Products, Reps and BusinessCategories), so each Category has only 6 rows of data in this table.
I want to generate an SQL statement that pulls the tables into columns that I can then parse into a json object like this:
{
categoryName: 'Folders',
warnInterval: 40,
errorInterval: 60,
groups: [{
groupName: 'Products',
Include: 'SomeProduct',
Exclude: 'SomeOtherProduct'
}, {
groupName: 'Reps',
Include: 'SomeRep',
Exclude: 'SomeOtherRep'
}, {
groupName: 'BusinessCategories',
Include: 'SomeCategory',
Exclude: 'SomeOtherCategory'
}]
}
I would like the SQL statement to join the 2 tables and present the data into columns like this:
CategoryName
WarnInterval
ErrorInterval
ProductTitle (this is the group name)
ProductIncludes (If the IncludedExcluded value is 'I' then put the match in this column)
ProductExcludes (If the IncludedExcluded value is 'E' then put the match in this column)
RepresentativeTitle
RepresentativeIncludes
RepresentativeExcludes
BusinessCategoryTitle
BusinessCategoryIncludes
BusinessCategoryExcludes
I really hope I explained that well. Can someone help me with the SQL for this? PS, it is Oracle :)
Maybe this is what you're after. The query really breaks the category_matches table into a set of six datasets - three groups * two include / exclude flags.
The list of columns in your question includes "ProductTitle (this is the group name)" which doesn't make sense since each of the groups is represented in each row of data. But maybe I have misunderstood
WITH
category_intervals (category_name, warn_interval, error_interval) AS
(SELECT 'Folders',40,60 FROM dual UNION ALL
SELECT 'catA',10,20 FROM dual UNION ALL
SELECT 'catB',50,100 FROM dual
)
,category_matches(category_name, group_name, include_exclude, match_name) AS
(SELECT 'Folders','Products','E','Product 1' FROM dual UNION ALL
SELECT 'Folders','Products','I','Product 2' FROM dual UNION ALL
SELECT 'Folders','Reps','E','Rep 1' FROM dual UNION ALL
SELECT 'Folders','Reps','I','Rep 2' FROM dual UNION ALL
SELECT 'Folders','Business Categories','E','Category 1' FROM dual UNION ALL
SELECT 'Folders','Business Categories','I','Category 2' FROM dual UNION ALL
--
SELECT 'catA','Products','E','Product 3' FROM dual UNION ALL
SELECT 'catA','Products','I','Product 4' FROM dual UNION ALL
SELECT 'catA','Reps','E','Rep 3' FROM dual UNION ALL
SELECT 'catA','Reps','I','Rep 4' FROM dual UNION ALL
SELECT 'catA','Business Categories','E','Category 3' FROM dual UNION ALL
SELECT 'catA','Business Categories','I','Category 4' FROM dual UNION ALL
--
SELECT 'catB','Products','E','Product 5' FROM dual UNION ALL
SELECT 'catB','Products','I','Product 6' FROM dual UNION ALL
SELECT 'catB','Reps','E','Rep 5' FROM dual UNION ALL
SELECT 'catB','Reps','I','Rep 6' FROM dual UNION ALL
SELECT 'catB','Business Categories','E','Category 5' FROM dual UNION ALL
SELECT 'catB','Business Categories','I','Category 6' FROM dual
)
SELECT
ci.category_name
,ci.warn_interval
,ci.error_interval
,ip.match_name product_include
,ep.match_name product_exclude
,ir.match_name rep_include
,er.match_name rep_exclude
,ibc.match_name bus_cat_include
,ibc.match_name bus_catt_exclude
FROM
category_intervals ci
,(SELECT *
FROM category_matches
WHERE group_name = 'Products'
AND include_exclude = 'I'
) ip
,(SELECT *
FROM category_matches
WHERE group_name = 'Products'
AND include_exclude = 'E'
) ep
,(SELECT *
FROM category_matches
WHERE group_name = 'Reps'
AND include_exclude = 'I'
) ir
,(SELECT *
FROM category_matches
WHERE group_name = 'Reps'
AND include_exclude = 'E'
) er
,(SELECT *
FROM category_matches
WHERE group_name = 'Business Categories'
AND include_exclude = 'I'
) ibc
,(SELECT *
FROM category_matches
WHERE group_name = 'Business Categories'
AND include_exclude = 'E'
) ebc
WHERE 1=1
AND ci.category_name = ip.category_name
AND ci.category_name = ep.category_name
AND ci.category_name = ir.category_name
AND ci.category_name = er.category_name
AND ci.category_name = ibc.category_name
AND ci.category_name = ebc.category_name
ORDER BY
ci.category_name
;

Resources