#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, только вы можете предложить это также