Как использовать оператор IN в данных таблицы при использовании Oracle SQL Developer? - PullRequest
1 голос
/ 10 октября 2019

У меня есть одна таблица, которая содержит столбцы и данные, как показано ниже:

KEY(string)  DAY(string)
1            (1,2,3,4)
2            (2,3,4,5)

Я бы хотел выбрать строку с 1 внутри столбца day. Поэтому я создаю следующее утверждение:

select * from test where 1 in day;

Я получил ошибку после выполнения этого:

ORA-01722: invalid number
01722. 00000 -  "invalid number"
*Cause:    The specified number was invalid.
*Action:   Specify a valid number.

Но если я напишу оператор, как показано ниже:

select * from test where 1 in (1,2,3,4,5);

Работает нормально.

Как использовать оператор IN в списке, хранящемся в таблице?

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

(1,2,3,4) - это не список или числа, это строка с символами '(', '1', ',', '2', ',', '3', ',', '4'и ')'.

Ваш запрос эффективен:

SELECT *
FROM   DUAL
WHERE  1 IN ( '(a,b,c,d)' )

, где символы a, b, c и d просто были заменены начисловые символы.

Вы получаете ошибку, потому что типы данных не совпадают, поскольку 1 - это число, а days - это строка (это не список чисел).

Вместо этого вы можете использовать:

select *
from   test
where  REPLACE( REPLACE( days, '(', ',' ), ')', ',' ) LIKE '%,' || 1 || ',%';

В качестве альтернативы, вы можете сохранить «список» как фактическую коллекцию / вложенную таблицу (а не строку с разделителями):

CREATE TYPE int_list IS TABLE OF INT;

CREATE TABLE test ( key NUMBER, days int_list )
  NESTED TABLE days STORE AS test__days;

INSERT INTO test ( key, days ) VALUES ( 1, int_list( 1, 2, 3, 4 ) );
INSERT INTO test ( key, days ) VALUES ( 2, int_list( 2, 3, 4, 5 ) );

Тогда выможно использовать:

SELECT *
FROM   test
WHERE  1 MEMBER OF days
0 голосов
/ 10 октября 2019

Это будет LIKE:

select * from test
where day like '%1%'

Предполагается, что в этом столбце нет 10, 11 или 31 дня, в противном случае LIKE найдет их все, что, вероятно, нечто ты хотел. В этом случае посмотрите, поможет ли %,1,% (что является простым «решением»).

Но, если дни «7 дней в неделе», исходное утверждение должно быть в порядке.


Если вам нужно сравнить номер сегодняшнего дня со значениями DAY, то посмотрите, поможет ли это: вам не нужно использовать юлианские даты, функцию MOD, что бы вы ни планировали сделать, как предлагает Oracle TO_CHAR D маска формата, которая возвращает номер дня. Например, сегодня четверг, 10 октября 2019 года. Функция возвращает

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> select sysdate today,
  2         to_char(sysdate, 'd') todays_number
  3  from dual;

TODAY      T
---------- -
10.10.2019 4

, поэтому вы можете использовать ее в like:

SQL> with test (key, day) as
  2    (select 1, '1,2,3,4' from dual union all
  3     select 2, '2,3,4,5' from dual
  4    )
  5  select key,
  6         day,
  7         to_char(sysdate, 'd') todays_number
  8  from test
  9  where day like '%' || to_char(sysdate, 'd') || '%';

       KEY DAY     T
---------- ------- -
         1 1,2,3,4 4
         2 2,3,4,5 4

SQL>

Если сегодня была, например, пятница25 октября 2019 года, тогда у вас будет

SQL> with test (key, day) as
  2    (select 1, '1,2,3,4' from dual union all
  3     select 2, '2,3,4,5' from dual
  4    )
  5  select key,
  6         day,
  7         to_char(date '2019-10-25', 'd') todays_number
  8  from test
  9  where day like '%' || to_char(date '2019-10-25', 'd') || '%';

       KEY DAY     T
---------- ------- -
         2 2,3,4,5 5

SQL>

В принципе, я думаю, что это может сработать.

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