简体   繁体   English

Oracle:DECODE和WHERE子句

[英]Oracle: DECODE and WHERE Clause

So I've been trying to deal with a poorly optimized/created database. 因此,我一直在尝试处理优化/创建效果不佳的数据库。 I know you can use decode within a where clause, but I was wondering if there was any way you could use the value in the where clause after decoding in the selection. 我知道您可以在where子句中使用解码,但是我想知道是否有任何方法可以在选择中进行解码后在where子句中使用该值。 Basically, I have a case sorta like this 基本上,我有这样的情况

DECODE(theRow, 'P', 1,'D',2,'T',3, ... (goes on a bit)) AS theRowDecoded

And I want to select the values between what might be sent in for that row (so say between 5 and 8). 我想在该行可能发送的值之间选择一个值(比如说5到8之间)。 Not sure why they didn't just use numbers for this column in the database (would make way more sense and easier programmatically), but oh well, gotta work with what I have. 不知道为什么他们不只是在数据库的此列中使用数字(这样可以使编程更有意义,更容易编程),但是,哦,可以使用我所拥有的东西。

So is there any way to use theRowDecoded in where or is there a better way to do a range? 那么,有什么方法可以在哪里使用theRowDecoded呢,还是有更好的方法来做范围? I know that DECODE is only an equals, but hoping there's a good way to do a range with decode. 我知道DECODE只是一个等值,但希望有一个很好的方法来进行解码范围。

You cannot use the alias in the where clause. 您不能在where子句中使用别名。 There are a couple of alternatives. 有两种选择。

Subquery 子查询

Make the query into a subquery an use the alias on a higher level. 使查询成为子查询,并在更高级别上使用别名。

SELECT
  theRowDecoded
FROM
  (SELECT
    DECODE(theRow, .....) as theRowDecoded
  FROM
    theTable)
WHERE
  theRowDecoded BETWEEN 5 AND 8

Use the original values 使用原始值

Perhaps better, because using the original values will also allow the use of indexes for your where clause. 也许更好,因为使用原始值还将允许在where子句中使用索引。 Also, it's shorter, not so nested, and therefor arguably more readable. 而且,它更短,没有那么嵌套,因此可以说更具可读性。

SELECT
  DECODE(theRow, .....) as theRowDecoded
FROM
  theTable
WHERE 
  theRow in ('T', 'X', 'Y', 'Z')

Virtual column 虚拟专栏

In the end, it might be better to change the table to numbers. 最后,将表更改为数字可能会更好。 You can make the number a function based virtual column . 您可以使数字成为function based virtual column That way, the numeric column also exists in the table and can be used as any other column, with that difference that it's updates automatically if you update theRow . 这样,数值列也存在于表中,并且可以用作任何其他列,不同之处在于,如果您更新theRow ,它会自动更新。

I've not used virtual columns myself, but it should work like this: 我自己没有使用虚拟列,但是它应该像这样工作:

alter table theTable
  add theRowDecoded int as generated always (decode(theRow, .....)) virtual;

Actual column 实际栏

Instead of a virtual column, you can also add an extra column and keep the two in sync with a trigger. 除了虚拟列,您还可以添加一个额外的列,并使两者与触发器保持同步。 Or you can remove theRow altogether. 或者,您可以完全删除theRow Since that might not be so easy, depending on your abilities and rights, and the application(s) that use this database, you might consider introducing a new column, and make the old column a virtual column, so it will still be available as a read-only legacy column during a transition period in which the software is updated to use your new numeric column. 由于根据您的能力和权限以及使用该数据库的应用程序,这可能并不容易,因此您可以考虑引入一个新列,并将旧列设置为虚拟列,因此仍然可以使用过渡期间的只读旧列,在该过渡期间,软件将更新为使用新的数字列。

you can repeat the same expression in the field list. 您可以在字段列表中重复相同的表达式。 I don't know if you can use its alias in the where clause (you'll have to try). 我不知道是否可以在where子句中使用其别名(必须尝试)。

what you can't do (afaik) is give an alias to an expression in the where clause and use it elsewhere. 您不能做的(afaik)是在where子句中为表达式赋予别名,并在其他地方使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM