在查询中使用人类可读的常量

时间:2014-02-19 13:46:37

标签: sql oracle

以下是一个示例查询:

SELECT thing_id
FROM thing
WHERE thing_type IN (3, 7)

我想将3和7转换为人类可读的名称,以帮助理解查询真正在做什么。像下面这样的东西会很棒:

SELECT thing_id
FROM thing
WHERE thing_type_id IN (OPENED, ONHOLD)

知道OPENED和ONHOLD会将其实际值声明在其他地方。

我想也可能有办法用thing_type表的JOIN来做到这一点。

请注意,我陷入了直接编码查询的环境,而不是使用抽象框架。

5 个答案:

答案 0 :(得分:5)

假设你有一个名为ThingNames的链接表,其中有两列,id和ThingName,你可以这样做

SELECT thing_id

FROM thing

LEFT JOIN ThingNames on thing.thing_type_id = ThingName.id

WHERE ThingNames.ThingName IN ('OPENED', 'ONHOLD')

(不要忘记括号内ThingNames周围的引号。

答案 1 :(得分:5)

您可以通过为值生成查找表来执行此操作:

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'));

我会推荐这样的方法。但你也可以这样做:

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);

这与您的原始查询最相似。

答案 2 :(得分:2)

已经提出了一些解决方案,但是如果你想避免一直加入类型表来获得描述,你可以创建一个UDF。但我不确定它会对表演造成什么样的负面影响。

SELECT thing_id
FROM thing
WHERE thing_type_id IN (udf_TypeIdFromCode('OPENED'), udf_TypeIdFromCode('ONHOLD'))

您也可以将类型代码作为视图的一部分,以便您可以执行以下操作:

SELECT thing_id
FROM vThing
WHERE thing_type_code IN ('OPENED', 'ONHOLD')

或者,如果它有意义并适用于您的域,您也可以将字符串代码作为id本身。我自己从来没有真正做到这一点,并且总是偏爱一个独特的约束附加code列,但我想这可能是一个可行的解决方案。

但是,为此目的添加额外code列的优点是,您只能将代码提供给实际需要在查询中引用的类型,从而消除了查找不需要代码的类型的代码的负担

答案 3 :(得分:1)

我认为OPENED和ONHOLD是字符串,而不是查询中的列。

可以这样做;如果您的数据库是关系型的,thing_type列应该有一个外键到另一个表中,该表将具有这些值。因此,您的查询变为:

select thing_id
  from thing t
  join thing_types tt
    on t.thing_type_id = tt.id
 where tt.description in ('OPENED', 'ONHOLD')

您可以通过查询USER_CONSTRAINTS来查看是否有外键。

select *
  from user_constraints
 where table_name = 'THING'

答案 4 :(得分:1)

没有使用in的另一种方法,我认为这会运行得更快,但你可以针对你的真实数据进行测试。

假设你有一个名为ThingNames的链接表,其中有两列,id和ThingName,你可以这样做

SELECT thing_id
FROM thing
where thing.thing_type_id in (select ThingName.id from ThingName WHERE ThingNames.ThingName IN ('OPENED', 'ONHOLD'))

表&从Diamond Fox的答案复制的列名