Oracle-从varchar2列中提取数字以进行比较

时间:2018-12-06 09:56:55

标签: sql oracle casting

我在解决任务时遇到了以下问题:

在Oracle数据库中,我有一个结构很简单的表ENTITY_INFO。它包含3列:

ENTITY_ID (VARCHAR2)-数据库中实体的PK

NAME (VARCHAR2)-信息的名称,即“位置”,“成本”,“最后遭遇”

VALUE (VARCHAR2)-信息的值,即“资产/音乐”,“ 1500”,“ 1.1.2000”

当前,我需要过滤出其“费用” <1000的实体。

天真的方法

SELECT ENTITY_ID FROM ENTITY_INFO WHERE NAME = 'cost' AND TO_NUMBER(VALUE)<1000

不起作用,因为列VALUE包含非数字值。 但是所有与过滤器NAME = 'cost'匹配的列值都是数字,因此我需要做的情况是有效的。

我找到了Select string as number on Oracle主题,但事实证明该信息对解决此问题没有帮助。

由于ENTITY_INFO的性质和项目状态,数据模型的更改也不是可行的解决方案。

感谢任何提示。

3 个答案:

答案 0 :(得分:4)

您可以有条件地转换为数字:

SELECT ENTITY_ID
FROM ENTITY_INFO
WHERE NAME = 'cost'
AND TO_NUMBER(CASE WHEN NAME = 'cost' THEN VALUE ELSE NULL END) < 1000

答案 1 :(得分:1)

利用WITH子句的另一种方法,假定所有带有name的记录都是数字

在tab1部分中,使用过滤条件并使用TO_NUMBER

从tab1查询
WITH tab1
     AS (SELECT entity_id, name, VALUE
           FROM entity_info
          WHERE name = 'cost')
SELECT *
  FROM tab1
 WHERE TO_NUMBER (VALUE) < 1000

在一列中包含数字和字符是等待发生的意外。添加另一列以区分数字和非数字不是一种选择,我认为如果namecost

,则有一个约束来阻止输入非数字

答案 2 :(得分:0)

在我的编译器中,我看不到您的代码有问题(或与此等效):

SELECT ENTITY_ID 
  FROM ENTITY_INFO
 WHERE NAME = 'cost'
   AND VALUE < 1000

数据样本示例:

with ENTITY_INFO as (
    select 1 as ENTITY_ID,  'cost' as name, '2000' as value from dual
    union all
    select 2 as ENTITY_ID,  'cost' as name, '900' as value from dual
    union all
    select 3 as ENTITY_ID,  'cost' as name, '3000' as value from dual
    union all
    select 4 as ENTITY_ID,  'cost' as name, '2500' as value from dual
    union all
    select 5 as ENTITY_ID,  'cost' as name, '700' as value from dual
    union all
    select 6 as ENTITY_ID,  'frf' as name, '250sasd0' as value from dual
    union all
    select 7 as ENTITY_ID,  'corfrst' as name, '70fa0' as value from dual
    )
SELECT ENTITY_ID 
  FROM ENTITY_INFO
 WHERE NAME = 'cost'
   AND VALUE < 1000

结果:

  

ENTITY_ID

    2

    5

或者,您可以使用子查询来确保从中得到的所有列值都是类似数字的字符串:

SELECT ENTITY_ID 
  FROM (SELECT ENTITY_ID,
               VALUE
          FROM ENTITY_INFO 
         WHERE NAME = 'cost' )
 WHERE TO_NUMBER(VALUE)<1000

希望我能帮上忙!