在ListAGG上使用instr

时间:2016-05-12 23:46:55

标签: regex oracle plsql oracle11g listagg

我想使用ListAgg然后在其上使用INSTR / REGEXPR来理解结果字符串是否具有字符串组合。

实施例

appNumber   Decision
123         AB
345         BC
123         PA
345         PA
123         AM

我想使用LISTAGG将它们列在一起,然后让INSTR说出LIST AGG是否同时具有" AB"和" AM"

结果将是

Appnumber         MyResult
123               1
345               0

有什么建议吗?

谢谢

2 个答案:

答案 0 :(得分:0)

我根本不打算使用LISTAGG;一个简单的sum + group by和几个case表达式也可以完成这项任务:

with sample_data as (select 123 appnumber, 'AB' decision from dual union all
                     select 345 appnumber, 'BC' decision from dual union all
                     select 123 appnumber, 'PA' decision from dual union all
                     select 345 appnumber, 'PA' decision from dual union all
                     select 123 appnumber, 'AM' decision from dual)
-- end of mimicking a table called "sample_data" that contains your data
select   appnumber,
         case when sum(distinct case when decision = 'AB' then 1 
                                     when decision = 'AM' then 2
                                     else 0
                                end) = 3 then 1
              else 0
         end myresult
from     sample_data
group by appnumber;

 APPNUMBER   MYRESULT
---------- ----------
       123          1
       345          0

这可以通过分配您正在搜索2的幂(1,2,4,8等)的值的每个决策,然后使用得到的不同值的总和来与总数进行比较。所有这些价值观。在你的情况下,你正在搜索2个字符串,所以你要检查一个等于3的总和(如果你检查是否存在3个字符串,它将是7(1 + 2 + 4),4个字符串将是15(1 + 2 + 4 + 8)等。

这是否比使用listagg的Tim的回答更有效率是任何人的猜测;我建议您测试两个版本,看看哪个版本最适合您的数据。

答案 1 :(得分:0)

如果您不限制使用ListAgg,我可能会建议您使用没有分析功能的其他解决方案。我使用集合让外部应用程序在一个像字符串数组的函数中传递你的状态('AB','AM')。此函数将结果集作为嵌套表返回。

初步类型声明:

create or replace type t_test_states is varray(10) of varchar2(2);
create or replace type t_test_appnumbers is table of number;

创建一个函数(在现实生活中,你不会使用子查询'ample_data'阻塞):

create or replace function TEST_GET_ANSWER (p_states IN t_test_states)
    return t_test_appnumbers 
  is
    v_resultset t_test_appnumbers;
  begin      
    with sample_data as (select 123 appnumber, 'AB' decision from dual union all
                         select 345 appnumber, 'BC' decision from dual union all
                         select 123 appnumber, 'PA' decision from dual union all
                         select 345 appnumber, 'PA' decision from dual union all
                         select 123 appnumber, 'AM' decision from dual)

    select appnumber bulk collect into v_resultset
      from (
            select appnumber
              from sample_data
             where decision in (select column_value from table(p_states))
             group 
                by appnumber
                 , decision     
           ) 
     group               
        by appnumber
    --the next condition ensures that appnumber has exactly ALL states
    having count(*) = (select count(column_value) from table(p_states));

    return v_resultset;
end TEST_GET_ANSWER;

使用该功能如下:

select * from table(test_get_answer(t_test_states('AB','AM')))
select * from table(test_get_answer(t_test_states('PH')))
select * from table(test_get_answer(t_test_states('PA')))
select * from table(test_get_answer(t_test_states()))