Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在查询中使用人类可读的常量_Sql_Oracle - Fatal编程技术网

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

Sql 在查询中使用人类可读的常量,sql,oracle,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_类型的表来实现这一点 请注意,我被困在一个

下面是一个查询示例:

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_类型的表来实现这一点


请注意,我被困在一个直接编写查询而不是使用抽象框架的环境中。

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

SELECT thing_id

FROM thing

LEFT JOIN ThingNames on thing.thing_type_id = ThingName.id

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

(别忘了括号中东西名周围的引号。

我假设OPENED和ONHOLD是字符串,而不是查询中的列

您可以这样做;如果您的数据库是关系数据库,
thing\u type
列应该在另一个表中包含一个外键,该表将包含这些值。因此,您的查询变成:

select thing_id
  from thing t
  join thing_types tt
    on t.thing_type_id = tt.id
 where tt.description in ('OPENED', 'ONHOLD')
您可以通过查询来确定是否存在外键


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

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

这与您最初的查询最为相似。

已经提出了一些解决方案,但是如果您不想一直加入类型表来获取描述,可以创建一个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
列用于此目的的优点是,您可以只为查询中实际需要引用的类型提供代码,从而消除了为不需要的类型查找代码的负担。

另一种方法是不使用join,我认为这会运行得更快,但您可以根据自己的真实数据


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

SELECT thing_id

FROM thing

LEFT JOIN ThingNames on thing.thing_type_id = ThingName.id

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

表和列名复制自Diamond Fox的答案

p.s如果还不明显,您需要在ThingNames表中填充所有不同事物的ID和名称(每一事物仅一行),并确保您的thing表中的thing_id与ThingName中的id相等。好的,由于where条件,
ThingName
将永远不会为
NULL
,但是
内部联接在这里不是更合适吗?也许会,但是左联接可以解决您提出的原始问题,尽管考虑到您的位置子句。为提升干杯。看起来就像我想的那样,使用文本ID指向特定条目,并在后台保留数字ID以进行实际连接。这是一种最佳实践还是该方法存在缺陷?Leokhorn-通常是的,这是标准的关系数据库设计最佳实践:除了最简单的数据库,它将节省您在主数据表中存储大量重复文本(这对性能非常不利)。对于不同的情况(内部、左侧、外部等),有不同类型的联接但是这超出了这个问题的范围,这个问题似乎很重复,但是如果你在几个不同的查询中需要这个逻辑,而我看不出它比物理查找表有什么优势?@plalx…这句话有什么意思吗:“我建议这样做。但你也可以这样做:”你不明白吗?我提供了第二种方法,因为它看起来更像OP的原始问题中的常量。你的两个建议都有相同的缺点…我不明白你的意思?我希望在DB中首先有查找表,但如果我不明白,这将是一个很好的补偿方法。感谢。确保有一个l看看我的答案。投票最多的一个在正确的轨道上,但不促进重用。使用代码列作为主键让我想知道性能影响。我一直看到数字ID用作主键,所以我猜这是有原因的。视图的想法是一个好主意。打开和保留应该是pe中的字符串rfect world,但我看到的表中的“类型”列只有数字,并且没有字符串列或查找表,可能只是一个字段注释,让您知道这些数字的含义。我认为类型列和数字没有问题(只要有外键)。我指的是,你在问题中没有将它们括在引号中,这意味着它们是列而不是字符串。我的意思是,当然,没有外键……只有数字,在某个开发人员的头脑中,它们只与抽象定义相链接。至于我的语法,我使用了Java的约定,其中包含常量在所有大写字母中。打开的将是一个包含数值的变量。