2017-04-03 65 views
1

我有以下查询:检查数组中是否有任何子串出现在字符串中?

select case when count(*)>0 then true else false end 
from tab 
where param in ('a','b') and position('T' in listofitem)>0 

此检查是否存在在列listofitem'T'如果确实如此的计数> 0。基本上,它是子串的搜索。

这在这个私人案件中效果很好。不过,我的真实情况是,我有text[]调用sub_array意味着多个值来检查。如何修改查询以处理sub_array类型?我更喜欢在查询中使用它,而不是使用LOOP的函数。

我actualy需要的是:

select case when count(*)>0 then true else false end 
from tab 
where param in ('a','b') and position(sub_array in listofitem)>0 

这因为sub_array不工作的类型是Text[]

+0

试试' unnest'阵列 –

回答

5

使用unnest() function扩大你的阵列& bool_and()(或bool_or() - 这取决于你想要什么样的比赛:所有数组元素,或至少一个)至aggregate

select count(*) > 0 
from tab 
where param in ('a','b') 
and (select bool_and(position(u in listofitem) > 0) 
     from unnest(sub_array) u) 
+0

我认为你误解了。 'T'只是一个例子。我需要用sub_array替换它。如果sub_array包含'3a','c','h'比我需要在tab表内搜索这三个字符串。 – avi

+0

@avi主要想法没有改变。使用unnest扩大汇总总结。实际的公式并不重要。 (我更新了我的答案)。 – pozs

+0

谢谢。在0 ...一个括号附近有太多的语法错误。但是,这仍然不适用于所有情况。如果我的行是“28713” 和“-1,37561,37560”。当sub_array ='37588','37560'时它找不到37560.但是,如果sub_array = 37561,37560它可以工作 – avi

0

强力方法是将数组转换为字符串:

select (count(*) > 0) as flag 
from tab 
where param in ('a','b') and 
     array_to_string(listofitem, '') like '%T%'; 

我应该注意,比较count(*)不是最有效的方法做这件事。我会建议,而不是:

select exists (select 1 
       from tab 
       where param in ('a','b') and 
        array_to_string(listofitem, '') like '%T%' 
      ) as flag; 

这停止在第一次匹配的逻辑,而不是计算所有匹配的行。

+0

如何将%T%替换为变量?我不能写'%sub_array%'。顺便说一下,它不会阻止第一场比赛的逻辑。内部查询将返回包含1的多行。 – avi

相关问题