как удалить одинарные кавычки из вывода внутреннего запроса в oracle sql

#sql #database #oracle

Вопрос:

Я хочу удалить одинарные кавычки из вывода внутреннего запроса следующим образом:

 select *from demo where codes in (select codes from demo_temp);
 

Типы данных бит-столбцов-varchar2

выход select codes from demo_temp составляет «201 601»

Я хочу, чтобы результат был таким

 select *from demo where codes in (201,601);---15rows
 

Я пробовал ниже, но это не работает:

 select *from demo where codes in replace((select codes from demo_temp),'''','');--0rows

select *from demo where codes in (select replace(codes,'''','') from demo_temp);--0rows
 

Комментарии:

1. Есть ли в вашей внутренней таблице одна строка с «201 601″? Или несколько строк со списками, разделенными запятыми? Или только одна строка на число, например » 201 » и «601»? Строки списка, разделенные запятыми, не принадлежат базе данных.

2. Я думаю, что это не очень хорошо объясняет, должен ли он был преобразовать значения, разделенные запятыми, в строки, или просто удалить одинарные кавычки, или и то, и другое

3. только одна строка с 201 601

4. мне нужно просто удалить одинарные кавычки из вывода внутреннего запроса

Ответ №1:

Один из вариантов-разбить codes на строки (в подзапросе):

 SELECT *
  FROM demo
 WHERE codes IN (    SELECT REGEXP_SUBSTR (TRIM (BOTH '''' FROM codes),
                                           '[^,] ',
                                           1,
                                           LEVEL)
                       FROM demo_temp
                 CONNECT BY LEVEL <= REGEXP_COUNT (codes, ',')   1);
 

Сработает ли это? Я думаю, да, если demo.codes содержит такие значения, как 201 и 601 .

Например: demo_temp.codes = '201,601' . Разбиение на строки, возврат запроса 201 и 601 (без одинарных кавычек):

 SQL> WITH demo_temp AS (SELECT q'['201,601']' codes FROM DUAL)
  2      SELECT codes,
  3             REGEXP_SUBSTR (TRIM (BOTH '''' FROM codes),
  4                            '[^,] ',
  5                            1,
  6                            LEVEL)
  7        FROM demo_temp
  8  CONNECT BY LEVEL <= REGEXP_COUNT (codes, ',')   1
  9  /

CODES     REGEXP_SU
--------- ---------
'201,601' 201
'201,601' 601

SQL>
 

Комментарии:

1. Есть ли какой-нибудь способ получить результат в виде 201 601 в той же строке?

2. Что это значит? Какой «тот же ряд»? Если вы говорите о том, что вы хотели бы получить (и опубликованный код ... where codes in (201,601) ), то забудьте об этом. Это просто так не сработает. Правильный способ-сделать то, что я предложил.

3. я также пробовал это: выберите regexp_substr(коды,’w ‘,1,1) коды из demo_temp; он возвращает 201, только вы можете предложить это также

4. Конечно. Похоже, вы не знаете синтаксиса REGEXP_SUBSTR, так что вам «повезло угадать». Я опубликовал код, который работает, поэтому предлагаю вам его использовать.

Ответ №2:

Поскольку постер вопроса требует динамического сравнения, давайте сделаем это с помощью простого теста. Идея состоит в том, чтобы показать исходный столбец без кавычек и значения в соединении, соответствующие любому из значений в строке с запятой

 SQL> create table t ( id number generated always as identity start with 1 increment by 1 , codes number ) ;

Table created.

SQL> insert into t ( codes ) values ( 201 ) ;

1 row created.

SQL> insert into t ( codes ) values ( 601 ) ;

1 row created.

SQL> insert into t ( codes ) values ( 309 ) ;

1 row created.

SQL> insert into t ( codes ) values ( 501 )  ;

1 row created.

SQL> commit ;

Commit complete.

SQL> select * from t ;

        ID      CODES
---------- ----------
         1        201
         2        601
         3        309
         4        501

SQL> create table x ( codes varchar2(20) ) ;

Table created.

SQL> insert into x values ( q'('201,601')' ) ;

1 row created.

SQL> insert into x values ( q'('309,501')') ;

1 row created.

SQL> commit ;

Commit complete.

SQL> select * from x ;

CODES
--------------------
'201,601'
'309,501'

SQL> with z ( lvl , codes )
    as
    ( select level lvl, regexp_substr ( codes, '[^,] ', 1, LEVEL) as codes
  from ( select replace(codes,'''','') as codes from x )
  connect by level <= regexp_count (codes, ',')   1
  )
  select t.id , t.codes from t
  where t.codes in ( select z.codes from z );

        ID      CODES
---------- ----------
         1        201
         2        601
         4        501
         3        309
 

Оригинал столбца в той же строке без кавычек

 SQL> with z ( lvl , codes )
as
( select level lvl, regexp_substr ( codes, '[^,] ', 1, LEVEL) as codes
  from ( select replace(codes,'''','') as codes from x )
  connect by level <= regexp_count (codes, ',')   1
)
select t.id , t.codes , replace(x.codes,'''','') as org_val 
from t cross join x 
where t.codes in ( select z.codes from z )
and
( t.codes like '%' || regexp_substr(replace(x.codes,'''',''),'[^,] ',1,1) || '%' 
  or 
  t.codes like '%' || regexp_substr(replace(x.codes,'''',''),'[^,] ',1,2) || '%'
);


       ID      CODES ORG_VAL
---------- ---------- --------------------
         1        201 201,601
         2        601 201,601
         4        501 309,501
         3        309 309,501
 

Комментарии:

1. Я рассмотрю первое решение, но вы жестко закодировали значения в предложении where как где заменить(коды,»»,») = ‘201,601’ , Мне нужно какое-то динамическое универсальное решение

2. @MuditB , вы ничего не сказали о динамике в своем первоначальном вопросе. позвольте мне показать вам это в том же ответе.

3. в моем ответе у вас есть решение, которое работает для любых данных, которые могут быть у вас в обеих таблицах

4. Есть ли какой-нибудь способ получить результат в виде 201 601 в той же строке?

5. я также пробовал это: выберите regexp_substr(коды,’w ‘,1,1) коды из demo_temp; он возвращает 201, только вы можете предложить это также