繁体   English   中英

NOT IN 无法与 Listagg function 一起按预期工作

[英]NOT IN is not working as expected with Listagg function

下面是表的DDL

  create or replace table  tempdw.blk_table;
   (
     db_name varchar,
     tbl_expr varchar
   );

   insert into  tempdw.blk_table  values ('edw','ABC%');
   insert into  tempdw.blk_table  values ('edw','EFG%');

   select * from tempdw.blk_table;

在此处输入图像描述

下面的代码不起作用,预计 output 不应返回任何

select * from tempdw.blk_table where tbl_expr not in (
       select regexp_replace(regexp_replace(replace(listagg(tbl_expr,','),',','\',\''),'^','\''),'$','\'') from tempdw.blk_table);

当我在下面运行代码时它工作正常,试图理解为什么它不适用于上面的代码

select * from tempdw.blk_table where tbl_expr NOT IN('ABC%','EFG%');

Au contraire代码运行良好。 您不了解包含逗号的字符串和字符串列表之间的区别。

不幸的是,很难弄清楚想要做什么,因为你的问题没有解释这一点。

我可以推测你想要类似的东西:

select bt.*
from blk_table bt
where db_name like tbl_expr;

然而,这只是一个猜测。

with data as (
    select * from values ('edw','ABC%'),('edw','ABC%') v(db_name,tbl_expr )
)
select * from data 
where tbl_expr not in (
       select regexp_replace(regexp_replace(replace(listagg(tbl_expr,','),',','\',\''),'^','\''),'$','\'') from data);

确实给出了你不想要的结果。 又名:

DB_NAME TBL_EXPR
edw ABC%
edw ABC%

因为您的子查询只有一行结果,因为您已将两个输入聚合为一行。

REGEXP_REPLACE( REGEXP_REPLACE( REPLACE( LISTAGG( TBL_EXPR,','),',','\',\''),'^','\''),'$','\'')
 'ABC%','ABC%'

NOT IN是完全匹配的。因此,如果我们从字符串更改为数字:

SELECT num, num in (2,3,4) FROM values (1),(3),(5) v(num);  

给出:

 NUM    NUM IN (2,3,4)
 1      0
 3      1
 5      0

所以你的NOT IN只会返回不在你所拥有的列表中的字符串......并且给定你的列表是相同输入的聚合,根据定义,它们并不相同。

回到字符串..

SELECT str
    ,str in ('str_a', 'str_b')
    ,str not in ('str_a', 'str_b')
from values ('a'),('str_b') v(str);

给出:

STR    STR IN ('STR_A', 'STR_B')    STR NOT IN ('STR_A', 'STR_B')
a       0                           1
str_b   1                           0

因此你得到的结果..

现在我怀疑你想要 LIKE 类型行为或 REGEX 匹配,但鉴于你正在构建列表,你知道你在那里做什么..

另请注意:

listagg(tbl_expr,',') AS a
    ,replace(a,',','\',\'') AS b
    ,regexp_replace(b,'^','\'') AS c
    ,regexp_replace(c,'$','\'') AS d

是你正在做的效果可以替换为

listagg('\'' || tbl_expr || '\'',',')

除非您希望带有嵌入逗号的字符串成为独立的“列表”项..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM