Сравнение чисел как строки в оракуле - PullRequest
0 голосов
/ 07 октября 2009

У меня есть сравнение в Oracle для двух чисел. 010 и 10. Они равны, пока числовое равенство касается; Однако мне нужно сравнить их как String. Я пытался to_char, но это не работает.

Существуют ли другие функции, которые позволили бы мне точно сравнивать числовое значение как строку?

------------ Чтобы прояснить все сомнения ---------------------

У меня есть три столбца адрес1 адрес2 и адрес3 Я хочу сравнить ТОЛЬКО цифры в объединении всех трех. так, например, если значения следующие:
адрес1 = 01 проспект парка
адрес2 = 20 золотых ворот
address3 = null

Затем я хотел бы сравнить данные в таблице, чтобы увидеть, не окажется ли какое-либо из сцепленных значений адресов 0120

.

Однако сейчас он уравнивает 120 и 0120, чего я не желаю.

Данные извлекаются и объединяются, поэтому не сохраняются в столбце определенного типа. Все, что мне нужно, это убедиться, что эти числа сравниваются «ТОЧНО», а не как числа.

Пожалуйста, предложите.

Приветствия

Ответы [ 5 ]

1 голос
/ 07 октября 2009

Единственный правильный способ проверки на точное совпадение будет

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>
1 голос
/ 07 октября 2009

Это то, что вы ищете?

Настройка некоторых примеров данных:

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  
1 голос
/ 07 октября 2009

Здесь у вас нет опции - вы либо сравниваете строки, либо числа.

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

при преобразовании в целое число все = 10.

Если вы начнете с целого числа 10, вы не сможете узнать, сколько лидирующих нулей должна иметь его «строковая» версия. Поэтому сохраняйте их все в виде строк или сравнивайте их в виде чисел, что означает «10» = «010» = «0010» = 10.

0 голосов
/ 07 октября 2009

У вас есть строковое поле:

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'

Так что даже если поле является строкой, если вы просто напишите =10 в предложении where, Oracle будет сравнивать их как числа. Если вы напишите ='10' Oracle будет сравнивать их как строки.

0 голосов
/ 07 октября 2009

Хранятся ли числа в виде varchars в БД? Если числа хранятся в целочисленных переменных, то 010 будет таким же, как 10.

SELECT 010 FROM DUAL 

вернет 10. Это означает, что если вы сохранили любое число с ведущими нулями в виде целого числа, вы потеряете ведущие нули. Вы не можете вернуть то, что потеряли.

Может быть, я вас неправильно понял, вы можете перефразировать ваш вопрос?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...