Reputation: 507
Here's an example query:
SELECT thing_id
FROM thing
WHERE thing_type IN (3, 7)
I would like to turn the 3 and 7 into human-readable names to help understand what the query is truly doing. Something like the following would be great:
SELECT thing_id
FROM thing
WHERE thing_type_id IN (OPENED, ONHOLD)
Knowing that OPENED and ONHOLD would have their actual values declared somewhere else.
I'm thinking there may also be a way to do this with a JOIN of a thing_type table.
Note that I'm stuck in an environment where I'm coding queries directly rather than using an abstraction framework.
Upvotes: 2
Views: 190
Reputation: 43718
A few solutions were proposed already, but if you want to avoid joining the types table all the time to get the descriptions you could create a UDF. I am not sure what kind of negative impact it could have on performances however.
SELECT thing_id
FROM thing
WHERE thing_type_id IN (udf_TypeIdFromCode('OPENED'), udf_TypeIdFromCode('ONHOLD'))
You could also make the type code part of a view already, so that you can do:
SELECT thing_id
FROM vThing
WHERE thing_type_code IN ('OPENED', 'ONHOLD')
Or, if it makes sense and apply to your domain, you could as well make the string code the id itself. I've never really done it myself and always favored a unique constrained additionnal code
column, but I guess it could be a viable solution.
However, the advantage of having an extra code
column for that purpose is that you can give codes only to types you actually need to reference in queries, removing the burden of finding codes for types which do not need one.
Upvotes: 2
Reputation: 4598
Another way without join using in, I think this would run faster, but you could test that against your real data.
Assuming you have a linked table called ThingNames where there are two columns, id and ThingName, you could do this
SELECT thing_id
FROM thing
where thing.thing_type_id in (select ThingName.id from ThingName WHERE ThingNames.ThingName IN ('OPENED', 'ONHOLD'))
Table & column names copied from Diamond Fox's answer
Upvotes: 1
Reputation: 1270081
You can do this by generating a lookup table for the values:
with Lookup(value, name) as (
select 3, 'OPENED' from dual union all
select 7, 'ONHOLD' from dual
)
SELECT thing_id
FROM thing t
WHERE thing_type_id IN (select value from Lookup where name in ('OPENED', 'ONHOLD'));
I would recommend an approach like this. But you could also do:
with thevalues as (
select 3 as OPENED, 7 as ONHOLD from dual
)
SELECT thing_id
FROM thing cross join
thevalues
WHERE thing_type_id IN (OPENED, ONHOLD);
This is most similar to your original query.
Upvotes: 5
Reputation: 4850
Assuming you have a linked table called ThingNames where there are two columns, id and ThingName, you could do this
SELECT thing_id
FROM thing
LEFT JOIN ThingNames on thing.thing_type_id = ThingName.id
WHERE ThingNames.ThingName IN ('OPENED', 'ONHOLD')
(Don't forget the quotes around the ThingNames in your in brackets.
Upvotes: 5
Reputation: 52883
I assume that OPENED and ONHOLD are meant to be strings, rather than columns in your queries.
You can do this; if your database is relational, the thing_type
column should have a foreign key into another table, which will have those values. Thus, your query becomes:
select thing_id
from thing t
join thing_types tt
on t.thing_type_id = tt.id
where tt.description in ('OPENED', 'ONHOLD')
You can find out if there's a foreign key by querying USER_CONSTRAINTS.
select *
from user_constraints
where table_name = 'THING'
Upvotes: 1