Reputation: 27
I have a requirement in which I have two tables one stores condition and the second stores lookup values.
For eg.
Table 1 (Condition Table):
Condition |
---|
"100000010073024" = "BILLED" |
"100000010073027" = "Not Billed" |
"100000010073026" = "Not Billed" Or "100000010073055" = "Billed" |
Table2(Lookup Values):
Lookup Id | Meaning |
---|---|
100000010073024 | Test |
100000010073027 | Test1 |
100000010073026 | Test2 |
100000010073055 | Test3 |
So I want results like:
Result |
---|
Test = "BILLED" |
Test1 = "Not Billed" |
Test2 = "Not Billed" Or Test3 = "Billed" |
So how can I achieve this through oracle sql?
Upvotes: 0
Views: 249
Reputation: 167982
The simplest method may be to refactor your conditions table to have each lookup id/term pair in a separate row:
CREATE TABLE conditions (id, lookup_id, term) AS
SELECT 1, 100000010073024, 'BILLED' FROM DUAL UNION ALL
SELECT 2, 100000010073027, 'Not Billed' FROM DUAL UNION ALL
SELECT 3, 100000010073026, 'Not Billed' FROM DUAL UNION ALL
SELECT 3, 100000010073055, 'Billed' FROM DUAL;
Then you could also add referential constraints to the lookups table.
ALTER TABLE conditions ADD CONSTRAINT conditions__lookup_id__fk
FOREIGN KEY (lookup_id) REFERENCES lookups(lookup_id);
The query is simply:
SELECT LISTAGG('"' || l.meaning || '" = "' || c.term || '"', ' OR ')
WITHIN GROUP (ORDER BY ROWNUM) AS result
FROM conditions c
INNER JOIN lookups l
ON (c.lookup_id = l.lookup_id)
GROUP BY c.id;
Which outputs:
RESULT "Test" = "BILLED" "Test1" = "Not Billed" "Test2" = "Not Billed" OR "Test3" = "Billed"
db<>fiddle here
Upvotes: 0
Reputation: 142713
Here's one option.
Based on sample data you posted:
SQL> with
2 t1 (condition) as
3 (select '"100000010073024" = "BILLED"' from dual union all
4 select '"100000010073027" = "Not Billed"' from dual union all
5 select '"100000010073026" = "Not Billed" Or "100000010073055" = "Billed"' from dual
6 ),
7 t2 (lookup_id, meaning) as
8 (select 100000010073024, 'Test' from dual union all
9 select 100000010073027, 'Test1' from dual union all
10 select 100000010073026, 'Test2' from dual union all
11 select 100000010073055, 'Test3' from dual
12 ),
13 --
Split conditions to rows (separated by "or") so that you could (in the final select
) work on each of them, separately:
14 -- split conditions to rows
15 splcon as
16 (select trim(regexp_substr(replace(upper(condition), 'OR', '#'), '[^#)]+', 1, column_value)) condition
17 from t1 cross join
18 table(cast(multiset(select level from dual
19 connect by level <= regexp_count(upper(condition), 'OR') + 1
20 ) as sys.odcinumberlist))
21 )
Join condition is made by instr
function (whether condition
contains lookup_id
or not):
22 select
23 b.meaning ||
24 replace(substr(s.condition, instr(s.condition, '=') - 1), '"', '') as result
25 from splcon s join t2 b on instr(s.condition, b.lookup_id) > 0;
RESULT
------------------------------
Test = BILLED
Test1 = NOT BILLED
Test2 = NOT BILLED
Test3 = BILLED
SQL>
Upvotes: 1