Sorry if the title is a bit misleading but I don't know how else to put it. Anyways back to problem at hand. I have 2 tables WSM(contains warehouse id, name and risk associated with it) and SUTSM_REP(store and warehouse relation). Below are values what they hold: WSM table
Every warehouse has a risk associated with it(4 risks categories - Low, Medium, High & Critical) and a store gets stuff from multiple warehouses. If a store gets stuff from 3 warehouses(say for eg w1(medium risk), w2(high), w3(low)) then the risk associated with the store is 'High'. Similarly if a store gets stuff from 2 warehouses - 1 with medium and another with low risk then the store gets 'Medium' risk. I hope I am clear with this point. I was asked to bring up the count of Stores with each risk. So what I did was I created another table with risk and risk id. I assigned 1 to Low, 2 to medium, 3 to high and 4 to critical. Then I joined the 3 tables along with max of risk id and then did a count of that. Below is my query :
select RID, count(sp_id)
from
(select a.sp_id, max(c.r_id) AS RID
from SUTSM_REP a,
WSM b,
wsm_rid c
where a.sm_id = b.sm_id and b.smr = c.smr
group by a.sp_id) t
group by RID;
And the result is : my query result
But boss doesn't want a 3rd table to be created and he wants Risk names (Low, Medium, High, Critical) instead of Risk IDs. So I modified the query to :
with t as (
select sm_id, sm_name, smr, DECODE(smr, 'Low', 1,
'Medium', 2,
'High', 3,
'Critical', 4,
0) RISK_ID
from wsm )
select rid, count(sp_id) from
( select sp_id, max(risk_id) rid
from (select a.sp_id, b.sm_id, b.risk_id
from SUTSM_REP a, t b
where a.sm_id=b.sm_id)
group by sp_id )
group by rid;
I created a temp table using the wsm and added the risk id to the risk category/level. And then used the same logic as earlier. Output of this query is :
We use Oracle SQL. Can anyone please help me or point me in the direction of how to get the names of Risk Categories/Levels? I am at my wits end here. Thanks in advance to any posters for their help.
Would it help to decode
the RISK_ID back into the respective categories? Sample below ..
with t as (
select sm_id, sm_name, smr, DECODE(smr, 'Low', 1,
'Medium', 2,
'High', 3,
'Critical', 4,
0) RISK_ID
from wsm )
select rid,
DECODE(rid, 1, 'Low',
2, 'Medium',
3, 'High',
4, 'Critical') smr,
count(sp_id) from
( select sp_id, max(risk_id) rid
from (select a.sp_id, b.sm_id, b.risk_id
from SUTSM_REP a, t b
where a.sm_id=b.sm_id)
group by sp_id )
group by rid;
Alternatively, you may use the rank
function
select smr, count(distinct sp_id) from (
select s.sp_id, w.smr,
rank () over (partition by s.sp_id order by
DECODE(smr, 'Low', 1,
'Medium', 2,
'High', 3,
'Critical', 4,
0) desc
) rnk
from wsm w
join sutsm_rep s on w.sm_id = s.sm_id
) where rnk = 1
group by smr
;
If this doesn't work, please share your expected output. Also, please consider using db fiddle. I've added a sample here .
It would be best to have a risk table holding the risk names and their relevance. If you are not allowed to create such table, create them as an ad-hoc view with WITH
on-the-fly.
The next step is getting the highest risk per store, which can be got with a join to above risk table and KEEP LAST
.
The last step is counting stores per risk.
with risks as
(
select 'Low' as smr, 1 as relevance from dual
union all
select 'Medium' as smr, 2 as relevance from dual
union all
select 'High' as smr, 3 as relevance from dual
union all
select 'Critical' as smr, 4 as relevance from dual
)
, store_risks as
(
select
sw.sp_id,
max(w.smr) keep (dense_rank last order by r.relevance) as risk,
max(r.relevance) as risk_sortkey
from sutsm_rep sw -- the store/warehouse bridge
join wsm w on w.sm_id = sw.sm_id -- the warehouses
join risks r on r.smr = w.smr -- the risks
group by sw.sp_id
)
select risk, count(*)
from store_risks
group by risk
order by max(risk_sortkey);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.