【问题标题】:how to remove single quotes from the output of inner query in oracle sql如何从oracle sql中的内部查询输出中删除单引号
【发布时间】:2021-09-23 05:36:49
【问题描述】:

我想从内部查询的输出中删除单引号:

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

第 2 列的数据类型是 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

【问题讨论】:

  • 你的内表有一行'201,601'吗?还是带有逗号分隔列表的多行?或者每个数字只有一行,如“201”和“601”?逗号分隔的列表字符串不属于数据库。
  • 我认为这并不能很好地解释他是将逗号分隔的值转换为行,还是删除单引号,或两者兼而有之
  • 一行只有 201,601
  • 我只需要从内部查询输出中删除单引号

标签: sql database oracle


【解决方案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 包含诸如201601 之类的值。

例如:demo_temp.codes = '201,601'。拆分成行,查询返回201601(不带单引号):

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>

【讨论】:

  • 有什么方法可以在同一行中得到 201,601 的输出?
  • 这是什么意思?哪个“同一行”?如果您正在谈论您想要获得的内容(并发布代码... where codes in (201,601)),那么请忘记它。它只是不会那样工作。正确的方法是按照我的建议去做。
  • 我也试过这个:select regexp_substr(codes,'\w+',1,1) codesfrom demo_temp;它只返回 201,你也可以就此提出建议
  • 当然可以。看起来好像您不知道 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

【讨论】:

  • 我会考虑第一个解决方案,但您已将 where 子句中的值硬编码为 where replace(codes,'''','') = '201,601' ,我需要一些动态通用解决方案
  • @MuditB ,您在原始问题中没有提及动态。让我在同一个答案中告诉你。
  • 您在我的回答中有一个适用于您在两个表中可能拥有的任何数据的解决方案
  • 有什么方法可以在同一行中得到 201,601 的输出?
  • 我也试过这个:select regexp_substr(codes,'\w+',1,1) codesfrom demo_temp;它只返回 201,你也可以就此提出建议
猜你喜欢
  • 1970-01-01
  • 2017-10-08
  • 2021-10-06
  • 1970-01-01
  • 2018-08-02
  • 2014-03-19
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多