在oracle中比较数字和字符串

发布于 2024-08-06 17:10:31 字数 464 浏览 8 评论 0原文

我在 Oracle 中比较了两个数字。 010 和 10。 就数字相等而言,它们是相等的;但是,我需要将它们作为字符串进行比较。我尝试了 to_char 但它不起作用。

是否还有其他函数可以让我将数值与字符串进行精确比较?

------------澄清大家的疑惑---------------------

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

那么我想比较表中的数据,看看是否有任何地址的串联值是 0120

但是现在它也将 120 与 0120 相等,这是我不希望的。

数据被提取和连接,因此不存储在某种类型的列中。我所需要的只是确保这些数字“完全”进行比较,而不是作为数字进行比较。

请建议。

干杯

I have a comparison in Oracle for two numbers. 010 and 10.
They are equal as long as numeric equality is concerned; however, I need to compare them as String. I tried to_char but it doesn't work.

Are there any other functions which would let me do exact comparison of numeric value as string?

------------To clarify everyone's doubt---------------------

I have three columns address1 address2 and address3
I want to compare ONLY the digits in the concatenation of all three. so for example if values are as follows:
address1 = 01 park avenue
address2 = 20 golden gate
address3 = null

then I would like to compare data in table to see if any of the addresses' concatenated value comes out to be 0120

However right now it's equalizing 120 also with 0120 which I do not desire.

Data is extracted and concatenated, so not stored in a type of column. All I need is to ensure, that these numbers are compared "EXACTLY" and not as numbers.

Please suggest.

Cheers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

佼人 2024-08-13 17:10:31

这就是你所追求的吗?

设置一些示例数据:

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  

Is this what you're after?

Set up some example data:

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;

Here's a query that will find 'duplicates' by ordering by the concatenated number string. We extract the numbers from the address using regexp_replace on the address concatenation.

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

If you're looking for matches to a specific address - try something like this:

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

For example:

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  
情丝乱 2024-08-13 17:10:31

您在这里实际上没有选择 - 您要么比较字符串,要么比较数字。

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

当转换为整数时,all = 10。

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

You don't really have an option here - you are either comparing strings - or numbers.

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

when converted to an Integer all = 10.

If you start with an integer 10, you have no way of knowing how many leading zeros the "string" version of it should have. So store them all as strings, or compare them as numbers - meaning "10" = "010" = "0010" = 10.

孤独难免 2024-08-13 17:10:31

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

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>

The one and only correct way to check for exact matches would be

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

(Substituting bind variables or other columns for the hardcoded values to taste).

The fact that you are ignoring this obvious solution suggests you have some motive for comparing concatenated strings, which you have not yet explained.

Matching by concatenation is troublesome, as you are discovering. It works providing all elements are populated and of a fixed length. Once we allow nulls or variable length values we are doomed. None of the following ought to match on the basis of equality of elements, but lo! through the magic of concatenation they do:

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>

The workaround for this problem is to explicitly demarcate the elements in the concatenated string. For instance if we separate the elements in that last example with tildes we no longer get a match...

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

no rows selected

SQL>
情魔剑神 2024-08-13 17:10:31

数字是否以 varchar 形式存储在数据库中?如果数字存储在整数变量中,则 010 将与 10 相同。

SELECT 010 FROM DUAL 

将返回 10。这意味着一旦将任何带有前导零的数字存储为整数,您就会丢失前导零。你无法拿回你失去的东西。

也许我理解错了你的意思,你能重新表述一下你的问题吗?

Are the numbers stored as varchars in the db? If the numbers are stored in integer variables then 010 will be same as 10.

SELECT 010 FROM DUAL 

will return 10. This means that once you have stored any number with leading zeros as an integer you lose the leading zeros. You can't get back what you have lost.

Maybe I have understood you wrongly, can you rephrase your question?

风吹雪碎 2024-08-13 17:10:31

你有一个字符串字段:

select '010' str from dual

下面的 select 将返回 1 行:

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

下面的 select 将不返回任何行:

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

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

You have a string field:

select '010' str from dual

The following select will return 1 row:

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

The following select will return no rows:

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

So even if the field is a string if you just write =10 in the where clause Oracle will compare them as numbers. If you write ='10' Oracle will compare them as strings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文