将数字作为字符串在oracle中进行比较

时间:2009-10-07 05:57:27

标签: oracle plsql

我在Oracle中对两个数字进行了比较。 010和10。 只要涉及数字平等,它们就是平等的;但是,我需要将它们比作String。我尝试过to_char但它不起作用。

是否还有其他功能可以让我将数值精确比较为字符串?

------------澄清每个人的疑问---------------------

我有三列address1 address2和address3 我想比较所有三个串联中的数字。例如,如果值如下:
地址1 = 01公园大道
地址2 = 20金门
address3 = null

然后我想比较表中的数据,看看是否有任何地址的连接值是0120

然而现在它也正在使用0120来平衡120,这是我不想要的。

提取和连接数据,因此不存储在一种列中。我需要的是确保这些数字“完全”而不是数字。

请建议。

干杯

5 个答案:

答案 0 :(得分:1)

你真的没有选择 - 你要么比较字符串 - 或数字。

The "strings":
"10"
"010"
"0010"
"00010"

转换为整数时全部= 10.

如果以整数10开头,则无法知道它的“字符串”版本应该有多少前导零。所以将它们全部存储为字符串,或将它们作为数字进行比较 - 意思是“10”=“010”=“0010”= 10.

答案 1 :(得分:1)

这就是你要追求的吗?

设置一些示例数据:

create table address as
select
    '01 park avenue' address1,
    '20 golden gate' address2,
    '30 test' address3
from
    dual;

insert into address
select
    '01 park avenue' address1,
    '20 golden gate' address2,
    null address3
from
    dual;

insert into address
select
    '01 park avenue' address1,
    '20 golden gate' address2,
    null address3
from
    dual;

commit;

这是一个通过串联数字字符串排序来查找“重复”的查询。我们在地址连接上使用regexp_replace从地址中提取数字。

select
    address1 || address2 || address3 address_concat,
    regexp_replace(address1 || address2 || address3, '[^[:digit:]]')
            address_numbers_only
from
    address
order by
    address_numbers_only;

如果您正在寻找与特定地址匹配的内容 - 请尝试以下方式:

select
    *
from
    address
where
    regexp_replace(address1 || address2 || address3, '[^[:digit:]]') = 
            regexp_replace(:v_address1 ||
                    :v_address2 || 
                    :v_address3, '[^[:digit:]]');

例如:

select
    *
from
    address
where
    regexp_replace(address1 || address2 || address3, '[^[:digit:]]') = 
            regexp_replace('01 park avenue' ||
                    '20 golden gate' || 
                    null, '[^[:digit:]]');

-- returns...

ADDRESS1        ADDRESS2        ADDRESS3
01 park avenue  20 golden gate  
01 park avenue  20 golden gate  

答案 2 :(得分:1)

检查完全匹配的唯一正确方法是

select whatever
from addresses
where address1 = '01'
and   address2 = '20'
and   address3 is null;

(用绑定变量或其他列代替硬编码值)。

你忽略了这个明显的解决方案这一事实表明你有一些动机来比较连接的字符串,你还没有解释过。

正如您所发现的那样,通过连接进行匹配很麻烦。它的工作原理是提供所有元素的填充和固定长度。一旦我们允许空值或可变长度值,我们就注定了。以下所有内容都不应该在元素相等的基础上匹配,而是 lo!通过连接的魔力来实现:

SQL> select * from dual
  2  where 1||23 = 12||3
  3  /

D
-
X

SQL> select * from dual
  2  where 1||null||2 = 1||2||null
  3  /

D
-
X

SQL>
SQL> select * from dual
  2  where 123||null||null = 1||2||3
  3  /

D
-
X

SQL>

此问题的解决方法是显式划分连接字符串中的元素。例如,如果我们将最后一个示例中的元素与波浪号分开,我们将不再获得匹配...

SQL> select * from dual
  2  where 123||'~'||null||'~'||null = 1||'~'||2||'~'||3
  3  /

no rows selected

SQL>

答案 3 :(得分:0)

数字是否存储为db中的varchars?如果数字存储在整数变量中,那么010将与10相同。

SELECT 010 FROM DUAL 

将返回10.这意味着一旦您以前导零存储任何数字作为整数,您将丢失前导零。你无法找回失去的东西。

也许我错误地理解了你,你能改写一下你的问题吗?

答案 4 :(得分:0)

你有一个字符串字段:

select '010' str from dual

以下选择将返回1行:

select * from (select '010' str from dual) where str=10

以下选择将不返回任何行:

select * from (select '010' str from dual) where str='10'

因此,即使字段是字符串,如果只是在where子句中编写=10,Oracle也会将它们作为数字进行比较。如果你写='10',Oracle会将它们作为字符串进行比较。