RAG PCT
------ ---
GREEN 100
AMBER 50
ORANGE 20
RED 0
I need an oracle query to result like (Suggest to use Inner Join or Outer Join)
if the given PCT >100 then Green
if the given PCT >=50 and PCT < 100 then AMBER
if the given PCT >=20 and PCT < 0 then ORANGE
else RED
You can implement the logic using CASE
, like :
SELECT pct, CASE
WHEN pct >= 100 THEN 'GREEN'
WHEN pct >= 50 THEN 'AMBER'
WHEN pct >= 20 then 'ORANGE'
ELSE 'RED'
END
FROM mytable
CASE
stops on the first matching condition (hence no need to write WHEN pct >= 50 AND pct < 100
for example, since pct >= 100
is already caught by the previous condition.
If you are using a separate table to store the lower bound of each interval (like myranges
), as shown in your example, and you are looking to JOIN
it with a table that cotains actual data (like mydata
), then it is a little more tricky : you would need to ensure that you are joining with the relevant range record :
SELECT d.*, r.*
FROM mydata d
INNER JOIN myranges r
ON d.value >= r.pct
AND (
LEAD (r.pct) OVER (ORDER BY pct) IS NULL
OR d.value < LEAD (r.pct) OVER (ORDER BY pct)
)
What you're asking for doesn't entirely make sense - you've said "Use a join" but have provided nothing to join to , but never mind. The following strictly implements your spec:
WITH cteData AS (SELECT 'GREEN' AS RAG, 100 AS PCT FROM DUAL UNION ALL
SELECT 'AMBER', 50 FROM DUAL UNION ALL
SELECT 'ORANGE', 20 FROM DUAL UNION ALL
SELECT 'RED', 0 FROM DUAL)
SELECT RAG, PCT, CASE
WHEN PCT > 100 THEN 'GREEN'
WHEN PCT >= 50 AND PCT < 100 THEN 'AMBER'
WHEN PCT >= 20 AND PCT < 0 THEN 'ORANGE'
ELSE 'RED'
END AS COLOR
FROM cteData;
When executed, the above produces:
RAG PCT COLOR
GREEN 100 RED
AMBER 50 AMBER
ORANGE 20 RED
RED 0 RED
And may Codd have mercy upon your soul.
If I understand you correctly, I think this might be something like what you're after:
WITH rag_data AS (SELECT 'GREEN' AS rag, 100 AS PCT FROM DUAL UNION ALL
SELECT 'AMBER' AS rag, 50 AS PCT FROM DUAL UNION ALL
SELECT 'ORANGE' AS rag, 20 AS PCT FROM DUAL UNION ALL
SELECT 'RED' AS rag, 0 AS PCT FROM DUAL),
sample_data AS (SELECT -1 NUM FROM dual UNION ALL
SELECT 0 NUM FROM dual UNION ALL
SELECT 1 NUM FROM dual UNION ALL
SELECT 19 NUM FROM dual UNION ALL
SELECT 20 NUM FROM dual UNION ALL
SELECT 21 NUM FROM dual UNION ALL
SELECT 49 NUM FROM dual UNION ALL
SELECT 50 NUM FROM dual UNION ALL
SELECT 51 NUM FROM dual UNION ALL
SELECT 99 NUM FROM dual UNION ALL
SELECT 100 NUM FROM dual UNION ALL
SELECT 101 NUM FROM dual)
SELECT NUM,
rag,
pct,
rn
FROM (SELECT sd.num,
rd.rag,
rd.pct,
row_number() OVER (PARTITION BY sd.num ORDER BY rd.pct DESC) rn
FROM sample_data sd
INNER JOIN rag_data rd ON sd.num >= rd.pct)
WHERE rn = 1;
NUM RAG PCT RN
---------- ------ ---------- ----------
0 RED 0 1
1 RED 0 1
19 RED 0 1
20 ORANGE 20 1
21 ORANGE 20 1
49 ORANGE 20 1
50 AMBER 50 1
51 AMBER 50 1
99 AMBER 50 1
100 GREEN 100 1
101 GREEN 100 1
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.