LISTAGG在WHERE子句中

时间:2018-12-11 05:47:20

标签: sql db2

我需要类似

的查询
select id,name from sample
where 
(:test IS NULL
 OR name IN (:test))
)

这可能吗?我不想使用内部查询。

3 个答案:

答案 0 :(得分:1)

您不能在IN中使用listagg,因为它只需要与一列匹配即可,这是行不通的。 尝试一个简单的方法:

select id,name from sample
where :test is null or
:test  in (select name from sample);

在您的where子句中,您将需要所有ID,即表中的名称。 :test是否为null或(:test)中的名称,它将给出所有行!!!

答案 1 :(得分:0)

尝试此查询:

SELECT id, name
FROM sample
WHERE :test LIKE CONCAT('%,', CONCAT(name, ',%'));

答案 2 :(得分:0)

您应该创建一些“字符串标记生成器”表函数。对于其他算法也可能有用。

create function regexp_tokenize(
  source clob(2M)
, pattern varchar(128))
returns table (seq int, tok varchar(4000))
contains sql
deterministic
no external action
return
select seq, tok
from xmltable('for $id in tokenize($s, $p) return <i>{string($id)}</i>' 
passing 
  source as "s"
, pattern as "p"
columns 
  seq for ordinality
, tok varchar(4000) path '.'
) t;

现在我们可以执行以下操作:

with sample (id, name) as (values
 (1, 'ex1')
,(2, 'ex2')
,(3, 'ex3')
)
select s.*
from sample s
join table(regexp_tokenize(coalesce('ex1,ex2', s.name), ',')) f on f.tok=s.name
--join table(regexp_tokenize(coalesce(cast(null as varchar(10)), s.name), ',')) f on f.tok=s.name
--join table(regexp_tokenize(coalesce(:test, s.name), ',')) f on f.tok=s.name
;

实际上,由于性能原因,最好为NULL和NOT NULL输入构造不同的语句。