Oracle:DECODE和WHERE子句

时间:2014-09-22 15:12:05

标签: sql oracle range decode

所以我一直在尝试处理一个优化不佳/创建的数据库。我知道你可以在where子句中使用decode,但我想知道在选择中解码后是否有任何方法可以使用where子句中的值。基本上,我有一个像这样的案例

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

我想选择该行可能发送的值之间的值(例如5到8之间)。不知道为什么他们不只是在数据库中使用这个列的数字(会以编程方式更有意义和更容易),但是哦,好吧,我必须使用我的工作。

那么有没有办法在哪里使用theRowDecoded或者有更好的方法来做范围?我知道DECODE只是一个等号,但希望有一个很好的方法来解码一个范围。

2 个答案:

答案 0 :(得分:3)

您不能在where子句中使用别名。有几种选择。

<强>子查询

使查询进入子查询,并使用更高级别的别名。

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

使用原始值

也许更好,因为使用原始值还允许使用where子句的索引。此外,它更短,不是那么嵌套,因此更具可读性。

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

虚拟列

最后,将表格更改为数字可能会更好。您可以将数字设为function based virtual column。这样,数字列也存在于表格中,可以用作任何其他列,但如果您更新theRow则会自动更新。

我自己没有使用虚拟列,但它应该像这样工作:

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

实际列

您还可以添加一个额外的列,而不是虚拟列,使两者与触发器保持同步。或者您可以完全删除theRow。由于这可能不是那么容易,取决于您的能力和权限,以及使用此数据库的应用程序,您可以考虑引入一个新列,并将旧列设置为虚拟列,因此它仍然可用作在过渡期间的只读旧版列,其中软件已更新为使用新的数字列。

答案 1 :(得分:0)

您可以在字段列表中重复相同的表达式。我不知道你是否可以在where子句中使用它的别名(你必须尝试)。

你不能做什么(afaik)是给where子句中的表达式别名并在别处使用它。