Oracle - Creating chain of values and calculate cumulative count [duplicate] - oracle

This question already has an answer here:
Oracle cumulative count using SYS_CONNECT_BY_PATH
(1 answer)
Closed 5 years ago.
I have an oracle table DM_TEMP_SUMMING_DVC_BY_FW with below columns and sample data.
Data below shows
-dmc_id ='408' there are 2109 devices which are having firmware_version='RT1' and it is the first firmware_version because image_prerequisite is null for this firmware_image.
-dmc_id ='408' there are 40 devices which are having firmware_version='RT2' moved from "RT1" and so on.
+-----------+-------+-----------------+------------+------------------+
device_count| dmc_id| firmware_version| cg_id |image_prerequisite|
+-----------+-------+-----------------+------------+------------------+
| 40 | 408 |RT2 |0000 |RT1 |
| 24 | 408 |RT3 |0000 |RT2 |
| 18 | 408 |RT4 |0000 |RT3 |
| 2109 | 408 |RT1 |0000 |null |
+-----------+-------+-----------------+------------+------------------+
The requirement is to create the chain of firmware_versions and the count of devices moving through the chain.
For example:
Firmware_version movement is RT1-->RT2-->RT3-->RT4
so the count of devices moved from RT1 to RT4 is (RT1+RT2+RT3+RT4)
count of devices moved from RT2 to RT4 is (RT2+RT3+RT4)
count of devices moved from RT3 to RT4 is (RT3+RT4)
count of devices at last firmware_version is RT4
+--------------------+-------+-----------------+-------+--------------------+
cumm_device_count | dmc_id| firmware_version| cg_id |chain |
+--------------------+-------+-----------------+-------+--------------------+
| 82(40+24+18) | 408 |RT2 |0000 |null/RT1/RT2 |
| 42(24+18) | 408 |RT3 |0000 |null/RT1/RT2/RT3 |
| 18 | 408 |RT4 |0000 |null/RT1/RT2/RT3/RT4|
| 2191(2109+40+24+18)| 408 |RT1 |0000 |null/RT1 |
+--------------------+-------+-----------------+-------+--------------------+
I have tried to use below query to generate the chain based on firmware_version and image_prerequisite but it is not returning the results as expected. This query is returning 28 records.
SELECT dmc_id, firmware_version, charging_group_id, image_prerequisite, SYS_CONNECT_BY_PATH(firmware_version,'/') TrackingFW
from DM_TEMP_SUMMING_DVC_BY_FW
where FIRMWARE_VERSION in ('RT1','RT2','RT3','RT4') and dmc_id='408' and charging_group_id='0000'
CONNECT BY NOCYCLE PRIOR firmware_version=image_prerequisite;
Please suggest query or procedure to solve this requirement.
Thanks in advance!

Try this one;
select
SYS_CONNECT_BY_PATH(firmware_version, '/') path_,
firmware_version,
device_count,
dmc_id,
cg_id ,
(
select sum(device_count)
from DM_TEMP_SUMMING_DVC_BY_FW t2
start with t1.firmware_version=t2.firmware_version CONNECT BY nocycle PRIOR firmware_version=image_prerequisite
) sum_device
from DM_TEMP_SUMMING_DVC_BY_FW t1
start with image_prerequisite is null CONNECT BY nocycle PRIOR firmware_version =image_prerequisite

Related

Oracle - Query Optimization - Query runs for a long time

I have a oracle query which is executed once a month to get the order details processed. This query is taking a painfully lot of time to execute. ( More than thirty mins ). Therefore I am trying to optimize this. I have a decent knowledge in Oracle and I will explain what I have tried so far. Still, it takes around 20 minutes to complete. This is the query. Oracle version is 11g.
SELECT store_typ, store_no, COUNT(order_no) FROM
(
SELECT DISTINCT(order_no), store.store_no, store.store_typ FROM
(
SELECT trx.order_no,trx.ADDED_DATE, odr.prod_typ, odr.store_no FROM daily_trx trx
LEFT OUTER JOIN
(
SELECT odr.order_no,odr.prod_typ,prod.store_no FROM order_main odr
LEFT OUTER JOIN ORDR_PROD_TYP prod
on odr.prod_typ = prod.prod_typ
) odr
ON trx.order_no= odr.order_no
) daily_orders ,
(SELECT store_no,store_typ FROM main_stores ) store
WHERE 1=1
and daily_orders.order_no !='NA'
and store.store_no = daily_orders.store_no
AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') <= to_date('31-05-2020 23:59:59','DD-MM-YYYY HH24:MI:SS')
)
GROUP BY store_typ, store_no
Background
order_main - This table has over 4 million records
I introduced index for order_no column which reduced time to execute.
My questions are as follows.
1) Will it help if I move date validation inside the inner query like this ?
SELECT store_typ, store_no, COUNT(order_no) FROM
(
SELECT DISTINCT(order_no), store.store_no, store.store_typ FROM
(
SELECT trx.order_no,trx.ADDED_DATE, odr.prod_typ, odr.store_no FROM daily_trx trx
LEFT OUTER JOIN
(
SELECT odr.order_no,odr.prod_typ,prod.store_no FROM order_main odr
LEFT OUTER JOIN ORDR_PROD_TYP prod
on odr.prod_typ = prod.prod_typ
) odr
ON trx.order_no= odr.order_no
WHERE to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') <= to_date('31-05-2020 23:59:59','DD-MM-YYYY HH24:MI:SS')
) daily_orders ,
(SELECT store_no,store_typ FROM main_stores ) store
WHERE 1=1
and daily_orders.order_no !='NA'
and store.store_no = daily_orders.store_no
--AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
--AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') <= to_date('31-05-2020 23:59:59','DD-MM-YYYY HH24:MI:SS')
)
GROUP BY store_typ, store_no
2) Could someone please suggest any other improvements that can be done to this query?
3) Additional indexing would help in any other tables / columns ? Only daily_trx and order_main tables are the tables that contains huge amount of data.
Some generall suggestions
Do not combine ANSI and Oracle Join Syntax in one Query
Do not use outer join if inner join can be used
Your inner subqueries use outer joins, but the final join to main_stores is an inner join
eliminating all rows with store_no is null - you may use inner joins with the same result.
Filter rows early
A suboptimal practice is to first join in a subquery and than filter relevant row with where conditions
Use simple predicated
If you want to constraint a DATE column do it this way
trx.ADDED_DATE >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
Use count distinct if appropriate
The select DISTINCTquery in the third line cam be eliminated if you use COUNT(DISTINCT order_no)
Applying all the above point I come to the following query
select
store.store_no, store.store_typ, count(DISTINCT trx.order_no) order_no_cnt
from daily_trx trx
join order_main odr on trx.order_no = odr.order_no
join ordr_prod_typ prod on odr.prod_typ = prod.prod_typ
join main_stores store on store.store_no = prod.store_no
where trx.ADDED_DATE >= date'2020-05-01' and
trx.ADDED_DATE < date'2020-06-01' and
trx.order_no !='NA'
group by store.store_no, store.store_typ
Performance Considereations
You process a month of data, so there will be probably a large number of transaction (say 100K+). In this case the best approach is to full scan the two large tables and perform HASH JOINs.
You can expect this execution plan
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 199K| 5850K| | 592 (2)| 00:00:08 |
|* 1 | HASH JOIN | | 199K| 5850K| | 592 (2)| 00:00:08 |
| 2 | TABLE ACCESS FULL | MAIN_STORES | 26 | 104 | | 3 (0)| 00:00:01 |
|* 3 | HASH JOIN | | 199K| 5070K| | 588 (2)| 00:00:08 |
| 4 | TABLE ACCESS FULL | ORDR_PROD_TYP | 26 | 104 | | 3 (0)| 00:00:01 |
|* 5 | HASH JOIN | | 199K| 4290K| 1960K| 584 (1)| 00:00:08 |
|* 6 | TABLE ACCESS FULL| ORDER_MAIN | 100K| 782K| | 69 (2)| 00:00:01 |
|* 7 | TABLE ACCESS FULL| DAILY_TRX | 200K| 2734K| | 172 (2)| 00:00:03 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("STORE"."STORE_NO"="PROD"."STORE_NO")
3 - access("ODR"."PROD_TYP"="PROD"."PROD_TYP")
5 - access("TRX"."ORDER_NO"="ODR"."ORDER_NO")
6 - filter("ODR"."ORDER_NO"<>'NA')
7 - filter("TRX"."ADDED_DATE"<TO_DATE(' 2020-06-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "TRX"."ORDER_NO"<>'NA' AND "TRX"."ADDED_DATE">=TO_DATE(' 2020-05-01
00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
If you have a partition option available you will massively profit by defining a monthly partitioning schema (alternative a daily partitioning) on the two tables DAILY_TRX and ORDER_MAIN.
If the above assumption is not correct and you have very few transactions in the selected time interval (say below 1K) - you will go better using the index access and NESTED LOOPS joins.
You will need this set of indices
create index daily_trx_date on daily_trx(ADDED_DATE);
create unique index order_main_idx on order_main (order_no);
create unique index ORDR_PROD_TYP_idx1 on ORDR_PROD_TYP(prod_typ);
create unique index main_stores_idx1 on main_stores(store_no);
The expected plan is as follows
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 92 | 2760 | 80 (4)| 00:00:01 |
|* 1 | HASH JOIN | | 92 | 2760 | 80 (4)| 00:00:01 |
|* 2 | TABLE ACCESS BY INDEX ROWID | DAILY_TRX | 92 | 1288 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | DAILY_TRX_DATE | 92 | | 3 (0)| 00:00:01 |
|* 4 | HASH JOIN | | 100K| 1564K| 75 (3)| 00:00:01 |
| 5 | MERGE JOIN | | 26 | 208 | 6 (17)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID| MAIN_STORES | 26 | 104 | 2 (0)| 00:00:01 |
| 7 | INDEX FULL SCAN | MAIN_STORES_IDX1 | 26 | | 1 (0)| 00:00:01 |
|* 8 | SORT JOIN | | 26 | 104 | 4 (25)| 00:00:01 |
| 9 | TABLE ACCESS FULL | ORDR_PROD_TYP | 26 | 104 | 3 (0)| 00:00:01 |
|* 10 | TABLE ACCESS FULL | ORDER_MAIN | 100K| 782K| 69 (2)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("TRX"."ORDER_NO"="ODR"."ORDER_NO")
2 - filter("TRX"."ORDER_NO"<>'NA')
3 - access("TRX"."ADDED_DATE">=TO_DATE(' 2020-06-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "TRX"."ADDED_DATE"<TO_DATE(' 2020-07-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss'))
4 - access("ODR"."PROD_TYP"="PROD"."PROD_TYP")
8 - access("STORE"."STORE_NO"="PROD"."STORE_NO")
filter("STORE"."STORE_NO"="PROD"."STORE_NO")
10 - filter("ODR"."ORDER_NO"<>'NA')
Check here how to get the execution plan of your query

Oracle - sys_connect_by_path functionality

I have below input data in table
+-----------+-------+-----------------+-----------------+------------------+-------------------+
device_count| dmc_id| firmware_version| charging_group_id|image_prerequisite| count_within_dmcid|
+-----------+-------+-----------------+-----------------+------------------+-------------------+
| 5 | 3345 |SU.B |0000000000000000 |SU.A | 93 |
| 6 | 3345 |SU.C |0000000000000000 |SU.B | 93 |
| 8 | 3345 |SU.D |0000000000000000 |SU.C | 93 |
| 8 | 3345 |SU.E |0000000000000000 |SU.C | 93 |
| 20 | 3345 |SU.F |0000000000000000 |SU.D | 93 |
| 20 | 3345 |SU.F |0000000000000000 |SU.E | 93 |
| 10 | 3345 |SU.G |0000000000000000 |SU.F | 93 |
| 11 | 3345 |SU.H |0000000000000000 |SU.F | 93 |
| 20 | 3345 |SU.I |0000000000000000 |SU.G | 93 |
| 20 | 3345 |SU.I |0000000000000000 |SU.H | 93 |
| 5 | 3345 |SU.A |0000000000000000 |null | 93 |
| 40 | 408 |RT2 |0000000000000000 |RT1 | 24028 |
| 24 | 408 |RT3 |0000000000000000 |RT2 | 24028 |
| 18 | 408 |RT4 |0000000000000000 |RT3 | 24028 |
| 2109 | 408 |RT1 |0000000000000000 |null | 24028 |
| 1 | 1422 |RT1 |0000000000000000 |null | 7 |
| 1 | 1422 |RT2 |0000000000000000 |RT1 | 7 |
| 1 | 408 |RT1 |HFOTA-0000000041 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000000334 |null | 2 |
| 1 | 408 |RT1 |HFOTA-0000000359 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000000441 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000001885 |null | 2 |
| 4 | 408 |SVP01 |0000000000000000 |null | 24028 |
| 11 | 408 |Sanity01 |0000000000000000 |null | 24028 |
| 1 | 408 |Sanity1 |0000000000000000 |null | 24028 |
| 6 | 408 |TB_HT01 |0000000000000000 |null | 24028 |
| 1 | 408 |TEST_1 |0000000000000000 |null | 24028 |
| 5 | 408 |TK_ST001 |0000000000000000 |null | 24028 |
| 2 | 3345 |FW.D |0000000000000000 |FW.C | 24028 |
| 8 | 3345 |FW.E |0000000000000000 |FW.D | 24028 |
| 4 | 3345 |FW.F |0000000000000000 |FW.E | 24028 |
+-----------+-------+-----------------+-----------------+------------------+-------------------+
I am using below query to create chain of firmware_version and finding cumulative count.
WITH t1 AS
(SELECT device_count,
dmc_id,
CASE
WHEN COUNT(image_prerequisite) OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) > 1
THEN
MIN(firmware_version)
--WITHIN GROUP (ORDER BY firmware_version)
OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) || '+N'
ELSE firmware_version
END firmware_version,
charging_group_id,
image_prerequisite,
count_within_dmcid
FROM dm_temp_summing_dvc_by_fw
),
t2 AS
(SELECT SUM(device_count) device_count,
dmc_id,
firmware_version,
charging_group_id,
image_prerequisite,
count_within_dmcid
FROM t1
GROUP BY dmc_id,
firmware_version,
charging_group_id,
image_prerequisite,
count_within_dmcid
),
t3 AS
(SELECT t.*,
LEVEL lev,
sys_connect_by_path(firmware_version, '/') AS chain,
connect_by_root(firmware_version) root_fw,
row_number() OVER (PARTITION BY dmc_id, charging_group_id, firmware_version, connect_by_root(firmware_version) ORDER BY LEVEL DESC, sys_connect_by_path(firmware_version, '/')) rn
FROM t2 t
START WITH image_prerequisite IS NULL
CONNECT BY nocycle PRIOR regexp_substr(firmware_version, '[^+]*') = image_prerequisite
AND PRIOR dmc_id = dmc_id
AND PRIOR charging_group_id = charging_group_id
)
SELECT chain,
root_fw,
firmware_version AS fw,
device_count AS cnt,
dmc_id,
charging_group_id,
count_within_dmcid,
SUM(device_count) over(PARTITION BY dmc_id, charging_group_id, root_fw ORDER BY lev DESC) AS cumm,
lev,
rn
FROM t3
ORDER BY dmc_id,
charging_group_id,
lev DESC;
Results Query is returning: It is not returning the chain for firmware_versions FW.D, FW.E, FW.F because we are using START WITH image_prerequisite IS NULL.
Please suggest a way we can address the chain of firmware which does not have the starting point (Image Prerequisite) as NULL.
CHAIN ROOT_FW FW CNT DMC_ID CG_ID LEV COUNT_WITHIN_DMCID RN CUMM
--------------------------------------------- ---------- --------------- ---------- ---------- ---------------- ---------- ------------------ ---------- ----------
/RT1/RT2/RT3/RT4 RT1 RT4 18 408 0000000000000000 4 24028 1 18
/RT1/RT2/RT3 RT1 RT3 24 408 0000000000000000 3 24028 1 42
/RT1/RT2 RT1 RT2 40 408 0000000000000000 2 24028 1 82
/SVP01 SVP01 SVP01 4 408 0000000000000000 1 24028 1 4
/RT1 RT1 RT1 2109 408 0000000000000000 1 24028 1 2191
/Sanity01 Sanity01 Sanity01 11 408 0000000000000000 1 24028 1 11
/Sanity1 Sanity1 Sanity1 1 408 0000000000000000 1 24028 1 1
/TB_HT01 TB_HT01 TB_HT01 6 408 0000000000000000 1 24028 1 6
/TEST_1 TEST_1 TEST_1 1 408 0000000000000000 1 24028 1 1
/TK_ST001 TK_ST001 TK_ST001 5 408 0000000000000000 1 24028 1 5
/RT1 RT1 RT1 1 408 HFOTA-0000000041 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000000334 1 2 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000000359 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000000441 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000001885 1 2 1 1
/RT1/RT2 RT1 RT2 1 1422 0000000000000000 2 7 1 1
/RT1 RT1 RT1 1 1422 0000000000000000 1 7 1 2
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N/SU.I SU.A SU.I 20 3345 0000000000000000 7 93 1 20
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N SU.A SU.G+N 21 3345 0000000000000000 6 93 1 41
/SU.A/SU.B/SU.C/SU.D+N/SU.F SU.A SU.F 20 3345 0000000000000000 5 93 1 61
/SU.A/SU.B/SU.C/SU.D+N SU.A SU.D+N 16 3345 0000000000000000 4 93 1 77
/SU.A/SU.B/SU.C SU.A SU.C 6 3345 0000000000000000 3 93 1 83
/SU.A/SU.B SU.A SU.B 5 3345 0000000000000000 2 93 1 88
/SU.A SU.A SU.A 5 3345 0000000000000000 1 93 1 93
Expected output:
CHAIN ROOT_FW FW CNT DMC_ID CG_ID LEV COUNT_WITHIN_DMCID RN CUMM
--------------------------------------------- ---------- --------------- ---------- ---------- ---------------- ---------- ------------------ ---------- ----------
/RT1/RT2/RT3/RT4 RT1 RT4 18 408 0000000000000000 4 24028 1 18
/RT1/RT2/RT3 RT1 RT3 24 408 0000000000000000 3 24028 1 42
/RT1/RT2 RT1 RT2 40 408 0000000000000000 2 24028 1 82
/SVP01 SVP01 SVP01 4 408 0000000000000000 1 24028 1 4
/RT1 RT1 RT1 2109 408 0000000000000000 1 24028 1 2191
/Sanity01 Sanity01 Sanity01 11 408 0000000000000000 1 24028 1 11
/Sanity1 Sanity1 Sanity1 1 408 0000000000000000 1 24028 1 1
/TB_HT01 TB_HT01 TB_HT01 6 408 0000000000000000 1 24028 1 6
/TEST_1 TEST_1 TEST_1 1 408 0000000000000000 1 24028 1 1
/TK_ST001 TK_ST001 TK_ST001 5 408 0000000000000000 1 24028 1 5
/RT1 RT1 RT1 1 408 HFOTA-0000000041 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000000334 1 2 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000000359 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000000441 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA-0000001885 1 2 1 1
/RT1/RT2 RT1 RT2 1 1422 0000000000000000 2 7 1 1
/RT1 RT1 RT1 1 1422 0000000000000000 1 7 1 2
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N/SU.I SU.A SU.I 20 3345 0000000000000000 7 93 1 20
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N SU.A SU.G+N 21 3345 0000000000000000 6 93 1 41
/SU.A/SU.B/SU.C/SU.D+N/SU.F SU.A SU.F 20 3345 0000000000000000 5 93 1 61
/SU.A/SU.B/SU.C/SU.D+N SU.A SU.D+N 16 3345 0000000000000000 4 93 1 77
/SU.A/SU.B/SU.C SU.A SU.C 6 3345 0000000000000000 3 93 1 83
/SU.A/SU.B SU.A SU.B 5 3345 0000000000000000 2 93 1 88
/SU.A SU.A SU.A 5 3345 0000000000000000 1 93 1 93
/FW.D/FW.E/FW.F FW.D FW.F 4 3345 0000000000000000 3 93 1 4
/FW.D/FW.E FW.D FW.E 8 3345 0000000000000000 2 93 1 12
/FW.D FW.D FW.D 2 3345 0000000000000000 1 93 1 14
As I wrote in the comment, if you modify the START WITH clause in this way:
START WITH image_prerequisite IS NULL
OR image_prerequisite NOT IN (
SELECT firmware_version FROM dm_temp_summing_dvc_by_fw
)
then FWD will be included as a beginning of the chain.
This query: http://sqlfiddle.com/#!4/e4e13/3
gives the following results:
WITH t1 AS
(SELECT device_count,
dmc_id,
CASE
WHEN COUNT(image_prerequisite) OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) > 1
THEN
MIN(firmware_version)
--WITHIN GROUP (ORDER BY firmware_version)
OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) || '+N'
ELSE firmware_version
END firmware_version,
charging_group_id,
image_prerequisite,
count_within_dmcid
FROM dm_temp_summing_dvc_by_fw
),
t2 AS
(SELECT SUM(device_count) device_count,
dmc_id,
firmware_version,
charging_group_id,
image_prerequisite,
count_within_dmcid
FROM t1
GROUP BY dmc_id,
firmware_version,
charging_group_id,
image_prerequisite,
count_within_dmcid
),
t3 AS
(SELECT t.*,
LEVEL lev,
sys_connect_by_path(firmware_version, '/') AS chain,
connect_by_root(firmware_version) root_fw,
row_number() OVER (PARTITION BY dmc_id, charging_group_id, firmware_version, connect_by_root(firmware_version) ORDER BY LEVEL DESC, sys_connect_by_path(firmware_version, '/')) rn
FROM t2 t
START WITH image_prerequisite IS NULL
OR image_prerequisite NOT IN (
SELECT firmware_version FROM dm_temp_summing_dvc_by_fw
)
CONNECT BY nocycle PRIOR regexp_substr(firmware_version, '[^+]*') = image_prerequisite
AND PRIOR dmc_id = dmc_id
AND PRIOR charging_group_id = charging_group_id
)
SELECT chain,
root_fw,
firmware_version AS fw,
device_count AS cnt,
dmc_id,
charging_group_id,
count_within_dmcid,
SUM(device_count) over(PARTITION BY dmc_id, charging_group_id, root_fw ORDER BY lev DESC) AS cumm,
lev,
rn
FROM t3
ORDER BY 1;
| CHAIN | ROOT_FW | FW | CNT | DMC_ID | CHARGING_GROUP_ID | COUNT_WITHIN_DMCID | CUMM | LEV | RN |
|-----------------------------------------|----------|----------|------|--------|-------------------|--------------------|------|-----|----|
| /FW.D | FW.D | FW.D | 2 | 3345 | 0000000000000000 | 24028 | 14 | 1 | 1 |
| /FW.D/FW.E | FW.D | FW.E | 8 | 3345 | 0000000000000000 | 24028 | 12 | 2 | 1 |
| /FW.D/FW.E/FW.F | FW.D | FW.F | 4 | 3345 | 0000000000000000 | 24028 | 4 | 3 | 1 |
| /RT1 | RT1 | RT1 | 2109 | 408 | 0000000000000000 | 24028 | 2191 | 1 | 1 |
| /RT1 | RT1 | RT1 | 1 | 1422 | 0000000000000000 | 7 | 2 | 1 | 1 |
| /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000041 | 1 | 1 | 1 | 1 |
| /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000334 | 2 | 1 | 1 | 1 |
| /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000001885 | 2 | 1 | 1 | 1 |
| /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000441 | 1 | 1 | 1 | 1 |
| /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000359 | 1 | 1 | 1 | 1 |
| /RT1/RT2 | RT1 | RT2 | 1 | 1422 | 0000000000000000 | 7 | 1 | 2 | 1 |
| /RT1/RT2 | RT1 | RT2 | 40 | 408 | 0000000000000000 | 24028 | 82 | 2 | 1 |
| /RT1/RT2/RT3 | RT1 | RT3 | 24 | 408 | 0000000000000000 | 24028 | 42 | 3 | 1 |
| /RT1/RT2/RT3/RT4 | RT1 | RT4 | 18 | 408 | 0000000000000000 | 24028 | 18 | 4 | 1 |
| /SU.A | SU.A | SU.A | 5 | 3345 | 0000000000000000 | 93 | 93 | 1 | 1 |
| /SU.A/SU.B | SU.A | SU.B | 5 | 3345 | 0000000000000000 | 93 | 88 | 2 | 1 |
| /SU.A/SU.B/SU.C | SU.A | SU.C | 6 | 3345 | 0000000000000000 | 93 | 83 | 3 | 1 |
| /SU.A/SU.B/SU.C/SU.D+N | SU.A | SU.D+N | 16 | 3345 | 0000000000000000 | 93 | 77 | 4 | 1 |
| /SU.A/SU.B/SU.C/SU.D+N/SU.F | SU.A | SU.F | 20 | 3345 | 0000000000000000 | 93 | 61 | 5 | 1 |
| /SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N | SU.A | SU.G+N | 21 | 3345 | 0000000000000000 | 93 | 41 | 6 | 1 |
| /SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N/SU.I | SU.A | SU.I | 20 | 3345 | 0000000000000000 | 93 | 20 | 7 | 1 |
| /SVP01 | SVP01 | SVP01 | 4 | 408 | 0000000000000000 | 24028 | 4 | 1 | 1 |
| /Sanity01 | Sanity01 | Sanity01 | 11 | 408 | 0000000000000000 | 24028 | 11 | 1 | 1 |
| /Sanity1 | Sanity1 | Sanity1 | 1 | 408 | 0000000000000000 | 24028 | 1 | 1 | 1 |
| /TB_HT01 | TB_HT01 | TB_HT01 | 6 | 408 | 0000000000000000 | 24028 | 6 | 1 | 1 |
| /TEST_1 | TEST_1 | TEST_1 | 1 | 408 | 0000000000000000 | 24028 | 1 | 1 | 1 |
| /TK_ST001 | TK_ST001 | TK_ST001 | 5 | 408 | 0000000000000000 | 24028 | 5 | 1 | 1 |
The only differences from your expected output are values in COUNT_WITHIN_DMCID column, I really don't get how they are calculated.

Oracle - cumulative counts within chain of records

I have an oracle table DM_TEMP_SUMMING_DVC_BY_FW with below columns and sample data. Data below shows
-dmc_id ='408' there are 2109 devices which are having firmware_version='RT1' and it is the first firmware_version because image_prerequisite is null for this firmware_image.
-dmc_id ='408' there are 40 devices which are having firmware_version='RT2' moved from "RT1" and so on.
The requirement is to create the chain of firmware_versions and the count of devices moving through the chain. For example:
Firmware_version movement is RT1-->RT2-->RT3-->RT4
so the count of devices moved from RT1 to RT4 is (RT1+RT2+RT3+RT4)
count of devices moved from RT2 to RT4 is (RT2+RT3+RT4)
count of devices moved from RT3 to RT4 is (RT3+RT4)
count of devices at last firmware_version is RT4
Below is the input data in table DM_TEMP_SUMMING_DVC_BY_FW
+-----------+-------+-----------------+-----------------+------------------+-------------------+
device_count| dmc_id| firmware_version| cg_id |image_prerequisite| count_within_dmcid|
+-----------+-------+-----------------+-----------------+------------------+-------------------+
| 40 | 408 |RT2 |0 |RT1 | 24028 |
| 24 | 408 |RT3 |0 |RT2 | 24028 |
| 18 | 408 |RT4 |0 |RT3 | 24028 |
| 2109 | 408 |RT1 |0 |null | 24028 |
| 1 | 1422 |RT1 |0 |null | 7 |
| 1 | 1422 |RT2 |0 |RT1 | 7 |
| 1 | 408 |RT1 |HFOTA-0000000041 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000000334 |null | 2 |
| 1 | 408 |RT1 |HFOTA-0000000359 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000000441 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000001885 |null | 2 |
| 4 | 408 |SVP01 |0 |null | 24028 |
| 11 | 408 |Sanity01 |0 |null | 24028 |
| 1 | 408 |Sanity1 |0 |null | 24028 |
| 6 | 408 |TB_HT01 |0 |null | 24028 |
| 1 | 408 |TEST_1 |0 |null | 24028 |
| 5 | 408 |TK_ST001 |0 |null | 24028 |
+-----------+-------+-----------------+-----------------+------------------+-------------------+
Query that I have executed:
SELECT
chain,
firmware_version as fw,
device_count as cnt,
dmc_id,
cg_id,
count_within_dmcid,
sum( device_count ) over ( partition by dmc_id, cg_id order by lev desc ) as cumm
FROM (
select t.* , level lev,
sys_connect_by_path( firmware_version, '/' ) as chain
from DM_TEMP_SUMMING_DVC_BY_FW t
START WITH image_prerequisite IS null
CONNECT BY nocycle PRIOR firmware_version=image_prerequisite
AND PRIOR dmc_id = dmc_id
AND PRIOR cg_id = cg_id
) x
order by dmc_id, cg_id, lev desc
;
Results Query is returning:
+-----------------+---------+-----+------+----------------+------------------+----+
chain |fw |cnt |dmc_id| cg_id |count_within_dmcid|cumm|
+-----------------+---------+-----+------+----------------+------------------+----+
|/RT1/RT2/RT3/RT4 | RT4 | 18| 408 | 0 | 24028 | 18|
|/RT1/RT2/RT3 | RT3 | 24| 408 | 0 | 24028 | 42|
|/RT1/RT2 | RT2 | 40| 408 | 0 | 24028 | 82|
|/Sanity1 |Sanity1 | 1 | 408 | 0 | 24028 |2219|
|/TB_HT01 |TB_HT01 | 6 | 408 | 0 | 24028 |2219|
|/Sanity01 |Sanity01 | 11| 408 | 0 | 24028 |2219|
|/SVP01 |SVP01 | 4 | 408 | 0 | 24028 |2219|
|/RT1 | RT1 |2109 | 408 | 0 | 24028 |2219|
|/TEST_1 |TEST_1 | 1 | 408 | 0 | 24028 |2219|
|/TK_ST001 |TK_ST001 | 5 | 408 | 0 | 24028 |2219|
|/RT1 |RT1 | 1 | 408 |HFOTA-0000000041| 1 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000000334| 2 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000000359| 1 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000000441| 1 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000001885| 2 | 1 |
|/RT1/RT2 |RT2 |1 |1422 | 0 | 7 | 1 |
|/RT1 |RT1 |1 |1422 | 0 | 7 | 2 |
+-----------------+---------+-----+------+----------------+------------------+----+
Expected Results:
+-----------------+---------+-----+------+----------------+------------------+----+
chain |fw |cnt |dmc_id| cg_id |count_within_dmcid|cumm|
+-----------------+---------+-----+------+----------------+------------------+----+
|/RT1/RT2/RT3/RT4 | RT4 | 18| 408 | 0 | 24028 | 18|
|/RT1/RT2/RT3 | RT3 | 24| 408 | 0 | 24028 | 42|
|/RT1/RT2 | RT2 | 40| 408 | 0 | 24028 | 82|
|/Sanity1 |Sanity1 | 1 | 408 | 0 | 24028 | 1 |
|/TB_HT01 |TB_HT01 | 6 | 408 | 0 | 24028 | 6 |
|/Sanity01 |Sanity01 | 11| 408 | 0 | 24028 | 11 |
|/SVP01 |SVP01 | 4 | 408 | 0 | 24028 | 4 |
|/RT1 | RT1 |2109 | 408 | 0 | 24028 |2191|
|/TEST_1 |TEST_1 | 1 | 408 | 0 | 24028 | 1 |
|/TK_ST001 |TK_ST001 | 5 | 408 | 0 | 24028 | 5 |
|/RT1 |RT1 | 1 | 408 |HFOTA-0000000041| 1 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000000334| 2 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000000359| 1 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000000441| 1 | 1 |
|/RT1 |RT1 |1 | 408 |HFOTA-0000001885| 2 | 1 |
|/RT1/RT2 |RT2 |1 |1422 | 0 | 7 | 1 |
|/RT1 |RT1 |1 |1422 | 0 | 7 | 2 |
+-----------------+---------+-----+------+----------------+------------------+----+
Please suggest any solution for this problem.
Thanks in advance!
Another scenario with the split chains -
Input data in DM_TEMP_SUMMING_DVC_BY_FW table.
+-----------+-------+-----------------+-----------------+------------------+-------------------+
device_count| dmc_id| firmware_version| cg_id |image_prerequisite| count_within_dmcid|
+-----------+-------+-----------------+-----------------+------------------+-------------------+
| 5 | 3345 |SU.B |0000000000000000 |SU.A | 93 |
| 6 | 3345 |SU.C |0000000000000000 |SU.B | 93 |
| 8 | 3345 |SU.D |0000000000000000 |SU.C | 93 |
| 8 | 3345 |SU.E |0000000000000000 |SU.C | 93 |
| 20 | 3345 |SU.F |0000000000000000 |SU.D | 93 |
| 20 | 3345 |SU.F |0000000000000000 |SU.E | 93 |
| 10 | 3345 |SU.G |0000000000000000 |SU.F | 93 |
| 11 | 3345 |SU.H |0000000000000000 |SU.F | 93 |
| 20 | 3345 |SU.I |0000000000000000 |SU.G | 93 |
| 20 | 3345 |SU.I |0000000000000000 |SU.H | 93 |
| 5 | 3345 |SU.A |0000000000000000 |null | 93 |
| 40 | 408 |RT2 |0000000000000000 |RT1 | 24028 |
| 24 | 408 |RT3 |0000000000000000 |RT2 | 24028 |
| 18 | 408 |RT4 |0000000000000000 |RT3 | 24028 |
| 2109 | 408 |RT1 |0000000000000000 |null | 24028 |
| 1 | 142 |RT1 |0000000000000000 |null | 7 |
| 1 | 142 |RT2 |0000000000000000 |RT1 | 7 |
| 1 | 408 |RT1 |HFOTA-0000000041 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000000334 |null | 2 |
| 1 | 408 |RT1 |HFOTA-0000000359 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000000441 |null | 1 |
| 1 | 408 |RT1 |HFOTA-0000001885 |null | 2 |
| 4 | 408 |SVP01 |0000000000000000 |null | 24028 |
| 11 | 408 |Sanity01 |0000000000000000 |null | 24028 |
| 1 | 408 |Sanity1 |0000000000000000 |null | 24028 |
| 6 | 408 |TB_HT01 |0000000000000000 |null | 24028 |
| 1 | 408 |TEST_1 |0000000000000000 |null | 24028 |
| 5 | 408 |TK_ST001 |0000000000000000 |null | 24028 |
+-----------+-------+-----------------+-----------------+------------------+-------------------+
This query is breaking in the path split scenario data.
SU.A (5) -- Level 1
|
SU.B (5) -- Level 2
|
SU.C (6) -- Level 3
/ \
(8) SU.D SU.E (8) -- Level 4
\ /
SU.F (20) -- Level 5
/ \
(10) SU.G SU.H (11) -- Level 6
\ /
SU.I (20) -- Level 7
Query used:
SELECT chain,
root_fw,
firmware_version,
device_count,
dmc_id,
charging_group_id,
count_within_dmcid,
SUM(device_count) over(PARTITION BY dmc_id, cg_id, root_fw ORDER BY lev DESC),
lev
FROM (SELECT t.*,
LEVEL lev,
sys_connect_by_path(firmware_version, '/') AS chain,
connect_by_root(firmware_version) root_fw
FROM dm_temp_summing_dvc_by_fw t
START WITH image_prerequisite IS NULL
CONNECT BY nocycle PRIOR firmware_version = image_prerequisite
AND PRIOR dmc_id = dmc_id
AND PRIOR cg_id = cg_id) x
ORDER BY dmc_id,
cg_id,
lev DESC;
Ouput query is returning:
+-----------------------------------+--------+--------+-------------+------+----------------+------------------+----+---+
chain |root_fw |fw |device_count |dmc_id| cg_id |count_within_dmcid|cumm|lev|
+-----------------------------------+--------+--------+-------------+------+----------------+------------------+----+---+
|/SU.A/SU.B/SU.C/SU.D/SU.F/SU.G/SU.I|SU.A |SU.I | 20 |3345 |0000000000000000|93 |80 |7 |
|/SU.A/SU.B/SU.C/SU.E/SU.F/SU.H/SU.I|SU.A |SU.I | 20 |3345 |0000000000000000|93 |80 |7 |
|/SU.A/SU.B/SU.C/SU.E/SU.F/SU.G/SU.I|SU.A |SU.I | 20 |3345 |0000000000000000|93 |80 |7 |
|/SU.A/SU.B/SU.C/SU.D/SU.F/SU.H/SU.I|SU.A |SU.I | 20 |3345 |0000000000000000|93 |80 |7 |
|/SU.A/SU.B/SU.C/SU.E/SU.F/SU.G |SU.A |SU.G | 10 |3345 |0000000000000000|93 |122 |6 |
|/SU.A/SU.B/SU.C/SU.D/SU.F/SU.G |SU.A |SU.G | 10 |3345 |0000000000000000|93 |122 |6 |
|/SU.A/SU.B/SU.C/SU.D/SU.F/SU.H |SU.A |SU.H | 11 |3345 |0000000000000000|93 |122 |6 |
|/SU.A/SU.B/SU.C/SU.E/SU.F/SU.H |SU.A |SU.H | 11 |3345 |0000000000000000|93 |122 |6 |
|/SU.A/SU.B/SU.C/SU.E/SU.F |SU.A |SU.F | 20 |3345 |0000000000000000|93 |162 |5 |
|/SU.A/SU.B/SU.C/SU.D/SU.F |SU.A |SU.F | 20 |3345 |0000000000000000|93 |162 |5 |
|/SU.A/SU.B/SU.C/SU.E |SU.A |SU.E | 8 |3345 |0000000000000000|93 |178 |4 |
|/SU.A/SU.B/SU.C/SU.D |SU.A |SU.D | 8 |3345 |0000000000000000|93 |178 |4 |
|/SU.A/SU.B/SU.C |SU.A |SU.C | 6 |3345 |0000000000000000|93 |184 |3 |
|/SU.A/SU.B |SU.A |SU.B | 5 |3345 |0000000000000000|93 |189 |2 |
|/SU.A |SU.A |SU.A | 5 |3345 |0000000000000000|93 |194 |1 |
|/RT1/RT2/RT3/RT4 |RT1 |RT4 | 18 |408 |0000000000000000|24028 |18 |4 |
|/RT1/RT2/RT3 |RT1 |RT3 | 24 |408 |0000000000000000|24028 |42 |3 |
|/RT1/RT2 |RT1 |RT2 | 40 |408 |0000000000000000|24028 |82 |2 |
|/Sanity1 |Sanity1 |Sanity1 | 1 |408 |0000000000000000|24028 |1 |1 |
|/TB_HT01 |TB_HT01 |TB_HT01 | 6 |408 |0000000000000000|24028 |6 |1 |
|/Sanity01 |Sanity01|Sanity01| 11 |408 |0000000000000000|24028 |11 |1 |
|/SVP01 |SVP01 |SVP01 | 4 |408 |0000000000000000|24028 |4 |1 |
|/RT1 |RT1 |RT1 | 2109 |408 |0000000000000000|24028 |2191|1 |
|/TEST_1 |TEST_1 |TEST_1 | 1 |408 |0000000000000000|24028 |1 |1 |
|/TK_ST001 |TK_ST001|TK_ST001| 5 |408 |0000000000000000|24028 |5 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000041|1 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000334|2 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000359|1 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000441|1 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000001885|2 |1 |1 |
|/RT1/RT2 |RT1 |RT2 | 1 |1422 |0000000000000000|7 |1 |2 |
|/RT1 |RT1 |RT1 | 1 |1422 |0000000000000000|7 |2 |1 |
+-----------------------------------+--------+--------+-------------+------+----------------+------------------+----+---+
Chain and cumulative counts are coming correct for regural chains A - B- C- D, but if we have split chains then it is doing summary of all the chain generated.
SU.A - 93 A+B+C+D+E+F+G+H+I
SU.B - 88 B+C+D+E+F+G+H+I
SU.C - 83 C+D+E+F+G+H+I
SU.D - 0 (Cummulative count will be zero if we have two or more FW at same level)
SU.E - 0 (Cummulative count will be zero if we have two or more FW at same level)
SU.F - 61 F+G+H+I
SU.G - 0 Cummulative count will be zero if we have two or more FW at same level)
SU.H - 0 Cummulative count will be zero if we have two or more FW at same level)
SU.I - 20 I
Expected output in this split scenario:
+---------------------------------------------+--------+--------+-------------+------+----------------+------------------+----+---+
chain |root_fw |fw |device_count |dmc_id| cg_id |count_within_dmcid|cumm|lev|
+---------------------------------------------+--------+--------+-------------+------+----------------+------------------+----+---+
|/SU.A/SU.B/SU.C/SU.D/SU.E/SU.F/SU.G/SU.H/SU.I|SU.A |SU.I | 20 |3345 |0000000000000000|93 |20 |7 |
|/SU.A/SU.B/SU.C/SU.D/SU.E/SU.F/SU.G/SU.H/ |SU.A |SU.H | 11 |3345 |0000000000000000|93 |0 |6 |
|/SU.A/SU.B/SU.C/SU.D/SU.E/SU.F/SU.G |SU.A |SU.G | 10 |3345 |0000000000000000|93 |0 |6 |
|/SU.A/SU.B/SU.C/SU.D/SU.E/SU.F |SU.A |SU.F | 20 |3345 |0000000000000000|93 |61 |5 |
|/SU.A/SU.B/SU.C/SU.D/SU.E |SU.A |SU.E | 8 |3345 |0000000000000000|93 |0 |4 |
|/SU.A/SU.B/SU.C/SU.D |SU.A |SU.D | 8 |3345 |0000000000000000|93 |0 |4 |
|/SU.A/SU.B/SU.C |SU.A |SU.C | 6 |3345 |0000000000000000|93 |83 |3 |
|/SU.A/SU.B |SU.A |SU.B | 5 |3345 |0000000000000000|93 |88 |2 |
|/SU.A |SU.A |SU.A | 5 |3345 |0000000000000000|93 |93 |1 |
|/RT1/RT2/RT3/RT4 |RT1 |RT4 | 18 |408 |0000000000000000|24028 |18 |4 |
|/RT1/RT2/RT3 |RT1 |RT3 | 24 |408 |0000000000000000|24028 |42 |3 |
|/RT1/RT2 |RT1 |RT2 | 40 |408 |0000000000000000|24028 |82 |2 |
|/Sanity1 |Sanity1 |Sanity1 | 1 |408 |0000000000000000|24028 |1 |1 |
|/TB_HT01 |TB_HT01 |TB_HT01 | 6 |408 |0000000000000000|24028 |6 |1 |
|/Sanity01 |Sanity01|Sanity01| 11 |408 |0000000000000000|24028 |11 |1 |
|/SVP01 |SVP01 |SVP01 | 4 |408 |0000000000000000|24028 |4 |1 |
|/RT1 |RT1 |RT1 | 2109 |408 |0000000000000000|24028 |2191|1 |
|/TEST_1 |TEST_1 |TEST_1 | 1 |408 |0000000000000000|24028 |1 |1 |
|/TK_ST001 |TK_ST001|TK_ST001| 5 |408 |0000000000000000|24028 |5 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000041|1 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000334|2 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000359|1 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000000441|1 |1 |1 |
|/RT1 |RT1 |RT1 | 1 |408 |HFOTA-0000001885|2 |1 |1 |
|/RT1/RT2 |RT1 |RT2 | 1 |1422 |0000000000000000|7 |1 |2 |
|/RT1 |RT1 |RT1 | 1 |1422 |0000000000000000|7 |2 |1 |
+---------------------------------------------+--------+--------+-------------+------+----------------+------------------+----+---+
It looks like what you're missing is partitioning on the root firmware_version, which you can get by using connect_by_root(), like so:
WITH dm_temp_summing_dvc_by_fw AS (SELECT 40 device_count, 408 dmc_id, 'RT2' firmware_version, '0000' cg_id, 'RT1' image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 24 device_count, 408 dmc_id, 'RT3' firmware_version, '0000' cg_id, 'RT2' image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 18 device_count, 408 dmc_id, 'RT4' firmware_version, '0000' cg_id, 'RT3' image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 2109 device_count, 408 dmc_id, 'RT1' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 1422 dmc_id, 'RT1' firmware_version, '0000' cg_id, NULL image_prerequisite, 7 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 1422 dmc_id, 'RT2' firmware_version, '0000' cg_id, 'RT1' image_prerequisite, 7 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA1' cg_id, NULL image_prerequisite, 1 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA2' cg_id, NULL image_prerequisite, 2 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA3' cg_id, NULL image_prerequisite, 1 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA4' cg_id, NULL image_prerequisite, 1 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA5' cg_id, NULL image_prerequisite, 2 count_within_dmcid FROM dual UNION ALL
SELECT 4 device_count, 408 dmc_id, 'SVP01' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 11 device_count, 408 dmc_id, 'Sanity01' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'Sanity1' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 6 device_count, 408 dmc_id, 'TB_HT01' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'TEST_1' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 5 device_count, 408 dmc_id, 'TK_ST001' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual)
SELECT chain,
root_fw,
firmware_version AS fw,
device_count AS cnt,
dmc_id,
cg_id,
lev,
count_within_dmcid,
SUM(device_count) over(PARTITION BY dmc_id, cg_id, root_fw ORDER BY lev DESC) AS cumm
FROM (SELECT t.*,
LEVEL lev,
sys_connect_by_path(firmware_version, '/') AS chain,
connect_by_root(firmware_version) root_fw
FROM dm_temp_summing_dvc_by_fw t
START WITH image_prerequisite IS NULL
CONNECT BY nocycle PRIOR firmware_version = image_prerequisite
AND PRIOR dmc_id = dmc_id
AND PRIOR cg_id = cg_id) x
ORDER BY dmc_id,
cg_id,
lev DESC;
Which gives the results:
CHAIN ROOT_FW FW CNT DMC_ID CG_ID LEV COUNT_WITHIN_DMCID CUMM
----------------- -------- -------- ---------- ---------- ------ ---------- ------------------ ----------
/RT1/RT2/RT3/RT4 RT1 RT4 18 408 0000 4 24028 18
/RT1/RT2/RT3 RT1 RT3 24 408 0000 3 24028 42
/RT1/RT2 RT1 RT2 40 408 0000 2 24028 82
/Sanity1 Sanity1 Sanity1 1 408 0000 1 24028 1
/TB_HT01 TB_HT01 TB_HT01 6 408 0000 1 24028 6
/Sanity01 Sanity01 Sanity01 11 408 0000 1 24028 11
/SVP01 SVP01 SVP01 4 408 0000 1 24028 4
/RT1 RT1 RT1 2109 408 0000 1 24028 2191
/TEST_1 TEST_1 TEST_1 1 408 0000 1 24028 1
/TK_ST001 TK_ST001 TK_ST001 5 408 0000 1 24028 5
/RT1 RT1 RT1 1 408 HFOTA1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA2 1 2 1
/RT1 RT1 RT1 1 408 HFOTA3 1 1 1
/RT1 RT1 RT1 1 408 HFOTA4 1 1 1
/RT1 RT1 RT1 1 408 HFOTA5 1 2 1
/RT1/RT2 RT1 RT2 1 1422 0000 2 7 1
/RT1 RT1 RT1 1 1422 0000 1 7 2
ETA:
With the additional requirement to handle cases where firmewares are at the same level as each other, I *think* this does what you're after:
WITH dm_temp_summing_dvc_by_fw AS (SELECT 40 device_count, 408 dmc_id, 'RT2' firmware_version, '0000' cg_id, 'RT1' image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 24 device_count, 408 dmc_id, 'RT3' firmware_version, '0000' cg_id, 'RT2' image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 18 device_count, 408 dmc_id, 'RT4' firmware_version, '0000' cg_id, 'RT3' image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 2109 device_count, 408 dmc_id, 'RT1' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 1422 dmc_id, 'RT1' firmware_version, '0000' cg_id, NULL image_prerequisite, 7 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 1422 dmc_id, 'RT2' firmware_version, '0000' cg_id, 'RT1' image_prerequisite, 7 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA1' cg_id, NULL image_prerequisite, 1 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA2' cg_id, NULL image_prerequisite, 2 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA3' cg_id, NULL image_prerequisite, 1 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA4' cg_id, NULL image_prerequisite, 1 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'RT1' firmware_version, 'HFOTA5' cg_id, NULL image_prerequisite, 2 count_within_dmcid FROM dual UNION ALL
SELECT 4 device_count, 408 dmc_id, 'SVP01' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 11 device_count, 408 dmc_id, 'Sanity01' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'Sanity1' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 6 device_count, 408 dmc_id, 'TB_HT01' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 1 device_count, 408 dmc_id, 'TEST_1' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 5 device_count, 408 dmc_id, 'TK_ST001' firmware_version, '0000' cg_id, NULL image_prerequisite, 24028 count_within_dmcid FROM dual UNION ALL
SELECT 5 device_count, 3345 dmc_id, 'SU.B' firmware_version, '0000' cg_id, 'SU.A' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 6 device_count, 3345 dmc_id, 'SU.C' firmware_version, '0000' cg_id, 'SU.B' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 8 device_count, 3345 dmc_id, 'SU.D' firmware_version, '0000' cg_id, 'SU.C' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 8 device_count, 3345 dmc_id, 'SU.E' firmware_version, '0000' cg_id, 'SU.C' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 20 device_count, 3345 dmc_id, 'SU.F' firmware_version, '0000' cg_id, 'SU.D' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 20 device_count, 3345 dmc_id, 'SU.F' firmware_version, '0000' cg_id, 'SU.E' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 10 device_count, 3345 dmc_id, 'SU.G' firmware_version, '0000' cg_id, 'SU.F' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 11 device_count, 3345 dmc_id, 'SU.H' firmware_version, '0000' cg_id, 'SU.F' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 20 device_count, 3345 dmc_id, 'SU.I' firmware_version, '0000' cg_id, 'SU.G' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 20 device_count, 3345 dmc_id, 'SU.I' firmware_version, '0000' cg_id, 'SU.H' image_prerequisite, 93 count_within_dmcid FROM dual UNION ALL
SELECT 5 device_count, 3345 dmc_id, 'SU.A' firmware_version, '0000' cg_id, NULL image_prerequisite, 93 count_within_dmcid FROM dual),
t1 AS (SELECT device_count,
dmc_id,
CASE WHEN COUNT(image_prerequisite) OVER (PARTITION BY dmc_id, cg_id, image_prerequisite) > 1
THEN listagg(firmware_version, '~') WITHIN GROUP (ORDER BY firmware_version) OVER (PARTITION BY dmc_id, cg_id, image_prerequisite)
ELSE firmware_version
END firmware_version,
cg_id,
image_prerequisite,
count_within_dmcid
FROM dm_temp_summing_dvc_by_fw),
t2 AS (SELECT sum(device_count) device_count,
dmc_id,
firmware_version,
cg_id,
image_prerequisite,
count_within_dmcid
FROM t1
GROUP BY dmc_id,
firmware_version,
cg_id,
image_prerequisite,
count_within_dmcid),
t3 AS (SELECT t.*,
LEVEL lev,
sys_connect_by_path(firmware_version, '/') AS chain,
connect_by_root(firmware_version) root_fw,
row_number() OVER (PARTITION BY dmc_id, cg_id, firmware_version, connect_by_root(firmware_version) ORDER BY LEVEL DESC, sys_connect_by_path(firmware_version, '/')) rn
FROM t2 t
START WITH image_prerequisite IS NULL
CONNECT BY nocycle PRIOR regexp_substr(firmware_version, '[^~]*') = image_prerequisite
AND PRIOR dmc_id = dmc_id
AND PRIOR cg_id = cg_id)
SELECT chain,
root_fw,
firmware_version AS fw,
device_count AS cnt,
dmc_id,
cg_id,
lev,
count_within_dmcid,
rn,
SUM(device_count) over(PARTITION BY dmc_id, cg_id, root_fw ORDER BY lev DESC) AS cumm
FROM t3
ORDER BY dmc_id,
cg_id,
lev DESC;
which gives us:
CHAIN ROOT_FW FW CNT DMC_ID CG_ID LEV COUNT_WITHIN_DMCID RN CUMM
--------------------------------------------- ---------- --------------- ---------- ---------- ------ ---------- ------------------ ---------- ----------
/RT1/RT2/RT3/RT4 RT1 RT4 18 408 0000 4 24028 1 18
/RT1/RT2/RT3 RT1 RT3 24 408 0000 3 24028 1 42
/RT1/RT2 RT1 RT2 40 408 0000 2 24028 1 82
/SVP01 SVP01 SVP01 4 408 0000 1 24028 1 4
/RT1 RT1 RT1 2109 408 0000 1 24028 1 2191
/Sanity01 Sanity01 Sanity01 11 408 0000 1 24028 1 11
/Sanity1 Sanity1 Sanity1 1 408 0000 1 24028 1 1
/TB_HT01 TB_HT01 TB_HT01 6 408 0000 1 24028 1 6
/TEST_1 TEST_1 TEST_1 1 408 0000 1 24028 1 1
/TK_ST001 TK_ST001 TK_ST001 5 408 0000 1 24028 1 5
/RT1 RT1 RT1 1 408 HFOTA1 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA2 1 2 1 1
/RT1 RT1 RT1 1 408 HFOTA3 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA4 1 1 1 1
/RT1 RT1 RT1 1 408 HFOTA5 1 2 1 1
/RT1/RT2 RT1 RT2 1 1422 0000 2 7 1 1
/RT1 RT1 RT1 1 1422 0000 1 7 1 2
/SU.A/SU.B/SU.C/SU.D~SU.E/SU.F/SU.G~SU.H/SU.I SU.A SU.I 20 3345 0000 7 93 1 20
/SU.A/SU.B/SU.C/SU.D~SU.E/SU.F/SU.G~SU.H SU.A SU.G~SU.H 21 3345 0000 6 93 1 41
/SU.A/SU.B/SU.C/SU.D~SU.E/SU.F SU.A SU.F 20 3345 0000 5 93 1 61
/SU.A/SU.B/SU.C/SU.D~SU.E SU.A SU.D~SU.E 16 3345 0000 4 93 1 77
/SU.A/SU.B/SU.C SU.A SU.C 6 3345 0000 3 93 1 83
/SU.A/SU.B SU.A SU.B 5 3345 0000 2 93 1 88
/SU.A SU.A SU.A 5 3345 0000 1 93 1 93
What this latest query does is first find out if there are firmwares that are at the same level as each other, and if so, we listagg them together (here, I've used ~ as a separator for clarity in the results - there's nothing to stop you from using the same separator as you use in the sys_connect_by_path).
Once we have that, we can do the connect by, but we need to look at just the first entry in the newly calculated firmware column (otherwise we won't find a match in the image_prerequisite column). Then it's just calculating the results in the same way the previous query did.

Oracle cumulative count using SYS_CONNECT_BY_PATH

When i have tried the below query on actual data it returned more number of records. Please help to resolve this issue.
Below is the actual data in table DM_TEMP_SUMMING_DVC_BY_FW
+-----------+-------+-----------------+------------+------------------+
device_count| dmc_id| firmware_version| cg_id |image_prerequisite|
+-----------+-------+-----------------+------------+------------------+
| 40 | 408 |RT2 |0000 |RT1 |
| 24 | 408 |RT3 |0000 |RT2 |
| 18 | 408 |RT4 |0000 |RT3 |
| 2109 | 408 |RT1 |0000 |null |
| 1 | 142 |RT1 |0000 |null |
| 1 | 142 |RT2 |0000 |RT1 |
| 1 | 408 |RT1 |HFOTA1 |null |
| 1 | 408 |RT1 |HFOTA2 |null |
| 1 | 408 |RT1 |HFOTA3 |null |
| 1 | 408 |RT1 |HFOTA4 |null |
| 1 | 408 |RT1 |HFOTA5 |null |
+-----------+-------+-----------------+------------+------------------+
Query that i have executed:
SELECT SYS_CONNECT_BY_PATH(firmware_version, '/') path_,
firmware_version,
device_count,
dmc_id,
charging_group_id ,
IMAGE_PREREQUISITE,
(SELECT SUM(device_count)
FROM DM_TEMP_SUMMING_DVC_BY_FW t2
START WITH t1.firmware_version =t2.firmware_version
CONNECT BY nocycle PRIOR firmware_version=image_prerequisite
) sum_device
FROM DM_TEMP_SUMMING_DVC_BY_FW t1
START WITH image_prerequisite IS NULL
CONNECT BY nocycle PRIOR firmware_version =image_prerequisite
Expected Result:
+--------------------+-------+-----------------+-------+--------------------+
cumm_device_count | dmc_id| firmware_version| cg_id |chain |
+--------------------+-------+-----------------+-------+--------------------+
| 82 | 408 |RT2 |0000 |null/RT1/RT2 |
| 42 | 408 |RT3 |0000 |null/RT1/RT2/RT3 |
| 18 | 408 |RT4 |0000 |null/RT1/RT2/RT3/RT4|
| 2191 | 408 |RT1 |0000 |null/RT1 |
| 2 | 142 |RT1 |0000 |null/RT1 |
| 1 | 142 |RT2 |0000 |null/RT1/RT2 |
| 1 | 408 |RT1 |HFOTA1 |null/RT1 |
| 1 | 408 |RT1 |HFOTA2 |null/RT1 |
| 1 | 408 |RT1 |HFOTA3 |null/RT1 |
| 1 | 408 |RT1 |HFOTA4 |null/RT1 |
| 1 | 408 |RT1 |HFOTA5 |null/RT1 |
+--------------------+-------+-----------------+-------+--------------------+
Actual returned results from query:
I have tried to use query to generate the chain based on firmware_version and image_prerequisite but it is not returning the results as expected. This query is returning more number of records.
/RT1 RT1 2109 408 0000000000000000 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1 RT1 1 408 HFOTA-0000001885 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1 RT1 1 408 HFOTA-0000000041 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1 RT1 1 408 HFOTA-0000000441 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1 RT1 1 408 HFOTA-0000000359 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1 RT1 1 408 HFOTA-0000000334 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1 RT1 1 1422 0000000000000000 2990
/RT1/RT2 RT2 40 408 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
/RT1/RT2 RT2 1 1422 0000000000000000 RT1 125
/RT1/RT2/RT3 RT3 24 408 0000000000000000 RT2 42
/RT1/RT2/RT3/RT4 RT4 18 408 0000000000000000 RT3 18
Expected results from the data stored in sqlfiddle: http://sqlfiddle.com/#!4/3cd9b/1
|/RT1/RT2/RT3/RT4| RT4 | 18 | 408| 0000000000000000| 24028| 18|
|/RT1/RT2/RT3 | RT3 | 24 | 408| 0000000000000000| 24028| 42|
|/AP1/AP2/AP3 | AP3 | 1 | 408| 0000000000000000| 24028| 1 |
|/RT1/RT2 | RT2 | 40 | 408| 0000000000000000| 24028| 82|
|/AP1/AP2 | AP2 | 2 | 408| 0000000000000000| 2 | 3 |
|/AP1 | AP1 | 1 | 408| 0000000000000000| 1 | 4 |
|/RT1 | RT1 |2109| 408| 0000000000000000| 24028|2191|
|/AS1 | AS1 | 1 | 408| 0000000000000000| 24028| 1 |
|/LRA1.NOV9.01 |LRA1.NOV9.01| 2 | 408| 0000000000000002| 106 | 2 |
|/LRA001 | LRA001 | 9 | 408| 0000000000000002| 106 | 9 |
|/LR1R_01 | LR1R_01 |15 | 408| 0000000000000002| 106 | 15|
|/APK29.2013 |APK29.2013 | 4 | 408| 0000000000000002| 106 | 4 |
|/APK2013.29 |APK2013.29 | 2 | 408| 0000000000000002| 106 | 2 |
|/ADR_TLRA1 |ADR_TLRA1 | 2 | 408| 0000000000000002| 106 | 2 |
|/ADR37 |ADR37 | 1 | 408| 0000000000000002| 106 | 1 |
|/A0 |A0 | 5 | 408| 0000000000000002| 106 | 5 |
|/36 |36 | 2 | 408| 0000000000000002| 106 | 2 |
|/LRA1_K01 |LRA1_K01 | 2 | 408| 0000000000000002| 106 | 2 |
|/abc |abc | 5 | 408| 0000000000000002| 106 | 5 |
|/VZW_U01 |VZW_U01 | 1 | 408| 0000000000000002| 106 | 1 |
|/VZW.NOV9.01 |VZW.NOV9.01 | 1 | 408| 0000000000000002| 106 | 1 |
|/TOSS_01 |TOSS_01 | 1 | 408| 0000000000000002| 106 | 1 |
|/TK_ST001 |TK_ST001 | 1 | 408| 0000000000000002| 106 | 1 |
|/SVP01 |SVP01 | 1 | 408| 0000000000000002| 106 | 1 |
|/LRA1v1 |LRA1v1 | 1 | 408| 0000000000000002| 106 | 1 |
|/LRA2_R01 |LRA2_R01 | 2 | 408| 0000000000000002| 106 | 2 |
|/MMY02-2013 |MMY02-2013 | 3 | 408| 0000000000000002| 106 | 3 |
|/PP0_MR1 |PP0_MR1 | 1 | 408| 0000000000000002| 106 | 1 |
|/RT1 |RT1 | 1 | 408| HFOTA-0000000041| 1 | 1 |
|/RT1 |RT1 | 1 | 408| HFOTA-0000000334| 2 | 1 |
|/RT1 |RT1 | 1 | 408| HFOTA-0000000359| 1 | 1 |
|/RT1 |RT1 | 1 | 408| HFOTA-0000000441| 1 | 1 |
|/RT1 |RT1 | 1 | 408| HFOTA-0000001885| 2 | 1 |
|/RT1/RT2 |RT2 | 1 | 1422| 0000000000000000| 7 | 1 |
|/RT1 |RT1 | 1 | 1422| 0000000000000000| 7 | 2 |
Solely with a trial and error over your SQL Fiddle sample data, this is the query returning your expected data:
SELECT SYS_CONNECT_BY_PATH(firmware_version, '/') path_,
firmware_version,
device_count,
dmc_id,
charging_group_id,
IMAGE_PREREQUISITE,
(SELECT SUM(device_count)
FROM DM_TEMP_SUMMING_DVC_BY_FW t2
START WITH t1.firmware_version = t2.firmware_version
and T1.dmc_id = T2.dmc_id
and T1.charging_group_id = T2.charging_group_id
CONNECT BY nocycle PRIOR firmware_version=image_prerequisite and prior dmc_id = dmc_id and prior charging_group_id = charging_group_id
) sum_device
FROM DM_TEMP_SUMMING_DVC_BY_FW t1
START WITH image_prerequisite IS NULL
CONNECT BY nocycle PRIOR firmware_version = image_prerequisite
and prior dmc_id = dmc_id
and prior charging_group_id = charging_group_id
Note: Yes, the charging_group_id and dmc_id are very important for your expected result, as krokodilko correctly mentioned in his above comment.

oracle 12c query is slow

below code works well in 11g BUT only in 12c works so slow (over 10 sec).
SELECT * FROM DMProgValue_00001
WHERE 1=1
AND ProgressOID IN (
SELECT P.OID FROM (
SELECT OID FROM (
SELECT A.OID, ROWNUM as seqNum FROM (
SELECT OID FROM DMProgress_00001 WHERE 1=1
AND Project = 'Q539'
ORDER BY actCode
) A
WHERE ROWNUM <= 40
) WHERE seqNum > 20
) P
);
Plan hash value: 763232015
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 189 | 171 (1)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL | DMPROGVALUE_00001 | 1 | 189 | 68 (0)| 00:00:01 |
|* 3 | VIEW | | 20 | 800 | 103 (1)| 00:00:01 |
|* 4 | COUNT STOPKEY | | | | | |
| 5 | VIEW | | 2916 | 78732 | 103 (1)| 00:00:01 |
|* 6 | SORT ORDER BY STOPKEY| | 2916 | 130K| 103 (1)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | DMPROGRESS_00001 | 2916 | 130K| 102 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( EXISTS (SELECT 0 FROM (SELECT "A"."OID" "OID",ROWNUM "SEQNUM" FROM
(SELECT "OID" "OID" FROM "DMPROGRESS_00001" "DMPROGRESS_00001" WHERE
"PHASE"='Construction' AND "PROJECT"='Q539' ORDER BY "ACTCODE") "A" WHERE ROWNUM<=40)
"from$_subquery$_003" WHERE "SEQNUM">20 AND "OID"=:B1))
3 - filter("SEQNUM">20 AND "OID"=:B1)
4 - filter(ROWNUM<=40)
6 - filter(ROWNUM<=40)
7 - filter("PHASE"='Construction' AND "PROJECT"='Q539')
DMProgress_0001 stats
NUM_ROW : 10385
BLOCKS : 370
AVG_ROW_LEN : 176
SMAPLE_SIZE : 8263
DMProgvalue_0001 stats
NUM_ROW : 15703
BLOCKS : 244
AVG_ROW_LEN : 49
SMAPLE_SIZE : 5033
It's only 10k rows and Indexs are well made ( I can tell because of 11g experience). I know some detour way to make fast ( below code - 0.001 sec) BUT I want to know real problem and fix it.
I cannot understand it only has one sub query and 10k rows for each table. Not just compared to 11g, There is no way that this query takes over 10 sec.
SELECT * FROM DMProgValue_00001 V,
(SELECT OID FROM (
SELECT A.OID, ROWNUM as seqNum FROM (
SELECT OID FROM DMProgress_00001 WHERE 1=1
AND Project = 'Q539'
ORDER BY actCode
) A
WHERE ROWNUM <= 40
) WHERE seqNum > 20
) P
WHERE 1=1
AND V.ProgressOID = P.OID;
added 11g similar query plan
Plan hash value: 3049049852
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 684 | 49 (5)| 00:00:01 |
|* 1 | HASH JOIN RIGHT SEMI | | 9 | 684 | 49 (5)| 00:00:01 |
| 2 | VIEW | VW_NSO_1 | 3 | 81 | 35 (3)| 00:00:01 |
|* 3 | VIEW | | 3 | 75 | 35 (3)| 00:00:01 |
|* 4 | COUNT STOPKEY | | | | | |
| 5 | VIEW | | 3 | 36 | 35 (3)| 00:00:01 |
|* 6 | SORT ORDER BY STOPKEY| | 3 | 144 | 35 (3)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | DMPROGRESS_00037 | 3 | 144 | 34 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | DMPROGVALUE_00037 | 5106 | 244K| 13 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("PROGRESSOID"="OID")
3 - filter("SEQNUM">20)
4 - filter(ROWNUM<=40)
6 - filter(ROWNUM<=40)
7 - filter("DISPLINE"='Q340' AND "PHASE"='Procurement' AND "PROJECT"='Moho')
oracle 11g automatically change the query as Hash join BUT 12c does not. I think this is point. They are same structure.

Resources