Прежде всего, важно помнить: Не хранить числа в типах символов.Используйте NUMBER
или INTEGER
.Во-вторых, всегда предпочитайте VARCHAR2
тип данных, а не CHAR
, если вы хотите хранить символы> 1.
В одном из ваших комментариев вы сказали, что столбец num1
имеет тип char(4)
.Проблема с типом данных CHAR
состоит в том, что если ваша строка имеет ширину 3 символа, она сохраняет запись, добавляя дополнительный 1 пробел, чтобы сделать ее 4 символа.VARCHAR2
сохраняет только столько символов, сколько вы пропустили при вставке / обновлении, и не заполняется пробелами.
Чтобы убедиться, что вы можете запустить select length(any_char_col) from t;
В связи с вашей проблемой, IN
условие никогда не выполняется, потому что на самом деле сравнивается:
WHERE 'abc ' = 'abc'
- обратите внимание на дополнительный пробел в левом операторе.
Чтобы исправить это, один хороший вариант - это заполнить выражение правой стороныс таким количеством пробелов, сколько требуется для правильного сравнения. Для этой цели можно использовать функцию RPAD( string1, padded_length [, pad_string] )
. Итак, ваш запрос должен выглядеть примерно так:
select * from table1 where num1 IN (select rpad(value,4) from table2);
Скорее всего, будет использоваться индекс для столбца num1
, если он существует.
Другой - использовать RTRIM
на LHS, что полезно только при наличии индекса на основе функцийRTRIM(num1)
select * from table1 where RTRIM(num1) in(select value from table2);
Итак, во всех этих примерах всегда используются типы NUMBER
для хранения чисел и предпочтение VARCHAR2
над CHAR
для строк.
См. Демо , чтобы полностью понять, что происходит.
РЕДАКТИРОВАТЬ : Кажется, вы храните числа, разделенные запятыми. Вы могли бы сделать что-то вроде этого.
SELECT *
FROM table1 t1
WHERE EXISTS (
SELECT 1
FROM table2 t2
WHERE ',' ||t2.value|| ',' LIKE '%,' || rtrim(t1.num1) || ',%'
);
См. Demo2
Хранение значений, разделенных запятыми, может вызвать проблемы, лучше их изменить.