Union results from subselect

此生再无相见时 提交于 2019-12-12 04:50:09

问题


I have an SQL statement with following structure:

f(string parameter)=select * from table(parameter) ...
=> results in some table with rows.

f(string parameter) is used as shortcut for more complex sql subquery.

table parameters:

|---params----|
   param1
   param2
   param3
   ....

how to combine f() with the table parameters where f() will be called for each param in this table. My question refers to SQL statement itself. As result I expect

f(param1)
  union all
f(param2)
  union all
f(param3)
...

If someone is interested what is staying in f() refer to my previous question answer https://stackoverflow.com/a/27599637/2023524.


回答1:


You can define f as a function like the below

create or replace function f(param IN VARCHAR2) return varchar2 is
  Result varchar2(32767);
begin
  with names as(
    SELECT REGEXP_SUBSTR(regexp_replace(replace(param,
                                                chr(13) || chr(10),
                                                ','),
                                        '[[:space:]]*',
                                        ''),
                         '[^=]+',
                         1,
                         level) as name
      FROM DUAL
    CONNECT BY LEVEL <= (SELECT REGEXP_COUNT(param, '=') FROM DUAL)

     )

      select LISTAGG(nvl(regexp_substr(name, '[^,]+', 1, 2),
                         regexp_substr(name, '[^,]+', 1)),
                     ',') WITHIN
       GROUP(
       ORDER BY name)
        INTO Result
        from names;

  return(Result);
end f;

Then you can call your parameters like the below

with parameter(param) as (
    select 'aa = black' ||chr(13)||chr(10)||'bb = change'||chr(13)||chr(10)||'mmmm=no'  
    from dual union  all
   select 'aa = black' ||chr(13)||chr(10)||'bb = change'||chr(13)||chr(10)||'kkk=no' from dual
    )
    select distinct regexp_substr(f(param),'[^,]+',1,level) from parameter
    connect by level <=regexp_count(f(param),',')+1;

Update1:-Just for your information You can call a function within an Anonymous Block like the below

DECLARE
  function f(param IN VARCHAR2) return varchar2 is
    Result varchar2(32767);
  begin
    with names as(
      SELECT REGEXP_SUBSTR(regexp_replace(replace(param,
                                                  chr(13) || chr(10),
                                                  ','),
                                          '[[:space:]]*',
                                          ''),
                           '[^=]+',
                           1,
                           level) as name
        FROM DUAL
      CONNECT BY LEVEL <= (SELECT REGEXP_COUNT(param, '=') FROM DUAL)

       )

        select LISTAGG(nvl(regexp_substr(name, '[^,]+', 1, 2),
                           regexp_substr(name, '[^,]+', 1)),
                       ',') WITHIN
         GROUP(
         ORDER BY name)
          INTO Result
          from names;


    return(Result);
  end f;
begin
  for i in 1 .. (regexp_count(f('aa = black' || chr(13) || chr(10) ||
                                'bb = change' || chr(13) || chr(10) ||
                                'kkk=no'),
                              ',') + 1) loop
    dbms_output.put_line(regexp_substr(f('aa = black' || chr(13) ||
                                         chr(10) || 'bb = change' ||
                                         chr(13) || chr(10) || 'kkk=no'),
                                       '[^,]+',
                                       1,
                                       i));
  end loop;
end;



回答2:


In Oracle 11g, I think you can just do this in the from clause:

with params as (
      select param1 as param from dual union all
      select param2 union all
      select param3
     )
select *
from params p,
     table(f(p.param)) f;


来源:https://stackoverflow.com/questions/27602170/union-results-from-subselect

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!