需要有关使用动态列编写SQL查询的帮助

时间:2017-01-13 11:05:03

标签: sql oracle

我必须编写一个查询,如下所示。我试过但不能写。请帮帮我。

我有一个返回结果集的表。

select * 
from table1;  --(rowid and ColumnName are columns of the table)

输出:

rowid       ColumnName
------------------------------
   1        Segment1    
   2        Segment2

我有另一个具有以下结构的表:( Segment1和Segment2是这里的列)

select *  
from table2; 

输出:

appId     Segment1     Segment2      Segment3
---------------------------------------------
  a1      fld1         fld2          per
  a2      cmp1         hcd4          klp 

我需要编写一个查询,它会读取" ColumnName"第一个表中的值,并检索第二个表中的列值。

这意味着,从table1,我将知道table2和table2中可用的列是什么,我将知道针对这些列存储的数据是什么。

如果我不清楚,请告诉我。 此查询位于Oracle SQL

4 个答案:

答案 0 :(得分:1)

如评论中所述,您需要一个带动态sql的PLSQL块。见下面的例子:

表:

create table table1 (row_id number,
                     ColumnName varchar2(100)) 

create table table2 (appId     number,   
                     Segment1  varchar2(100),
                     Segment2  varchar2(100),    
                     Segment3  varchar2(100));

 Insert all   
    into TABLE1 (ROW_ID, COLUMNNAME)  Values    (1, 'Segment1')
    into TABLE1 (ROW_ID, COLUMNNAME)  Values    (2, 'Segment2')
    into TABLE2 (APPID, SEGMENT1, SEGMENT2, SEGMENT3)  Values  (1, 'RRR', 'KKK', 'MMM')
    into TABLE2 (APPID, SEGMENT1, SEGMENT2, SEGMENT3)  Values  (2, 'ZZZ', 'PPP', 'QQQ')
    into TABLE2 (APPID, SEGMENT1, SEGMENT2, SEGMENT3)  Values  (3, 'LLL', 'NNN', 'DDD')
 select * from dual;

代码:

DECLARE
   var     VARCHAR2 (1000);
   v_sql   VARCHAR2 (2000);
   TYPE x_var IS TABLE OF VARCHAR2(1000);
   z_var   x_var;
   num number:=0;
BEGIN
   FOR rec IN (  SELECT DISTINCT columnname
                   FROM table1
                  ORDER BY 1)
   LOOP          
      num := num +1;      
      if num = 1 then
       var:= rec.columnname;       
       else
         var := var || ' || '' , ''||' || rec.columnname;
      end if; 

   END LOOP;

   var := RTRIM (LTRIM (var, ','), ',');   

   v_sql := 'select '|| var ||' from table2';    

   EXECUTE IMMEDIATE v_sql BULK COLLECT INTO z_var;

   FOR i IN 1 .. z_var.COUNT
   LOOP
      DBMS_OUTPUT.put_line (z_var(i));
   END LOOP;
END;

输出:

SQL> /
RRR , KKK
ZZZ , PPP
LLL , NNN

答案 1 :(得分:1)

SQL语句中的动态列几乎总是一个坏主意。通常有一种方法可以避免这些问题,并构建一个更简单的解决方案。

但是,如果这是真正需要在SQL中运行动态SQL的极少数时间之一,那么您需要安装和运行类似我的开源项目{{3} }。

例如:

create table table1 as
select 1 id, 'Segment1' columnName from dual union all
select 2 id, 'Segment2' columnName from dual;

create table table2 as
select 'a1' appId, 'fld1' Segment1, 'fld2' Segment2, 'per' Segment3 from dual union all
select 'a2' appId, 'cmp1' Segment1, 'hcd4' Segment2, 'klp' Segment3 from dual;

select * from table(method4.dynamic_query(
    q'[
        select
              'select appID, '
            ||listagg(columnName, ',') within group (order by id)
            ||' from table2'
            sql_statement
        from table1
    ]'
));

APPID   SEGMENT1   SEGMENT2
-----   --------   --------
a1      fld1       fld2
a2      cmp1       hcd4

以这种方式运行有很多缺点。代码复杂,缓慢,并且有一些奇怪的行为。有关其工作原理的说明,请参阅Method4  作者:Adrian Billington。

答案 2 :(得分:0)

以下PL SQL块是否有助于满足您的要求。

BEGIN
FOR iter IN (
                SELECT column_name
                FROM all_tab_columns
                WHERE upper(table_name) = 'table1'
                AND UPPER(column_name) LIKE 'SEGMENT%'
            )       
        LOOP
            SELECT iter.column_name INTO temp_table FROM table1
            dbms_output.put_line(temp_table.column_name);
        END LOOP;
END;
/

答案 3 :(得分:0)

假设您有以下表格:

SQL> select * from someTable;

   COLUMN1    COLUMN2    COLUMN3
---------- ---------- ----------
         1          2          3
         2          4          6
         3          6          9

SQL> select * from tableOfColumns;

COLUMNN
-------
column1
column3

您可能需要以下内容:

SQL> declare
  2      type    tListOfResults is table of varchar2(1000);
  3      vSQL    varchar2(1000);
  4      vResult tListOfResults ;
  5  begin
  6      select 'select ' || listagg (columnName, ' || '', '' || ') within group (order by columnName) || ' from someTable'
  7      into vSQL
  8      from tableOfColumns;
  9      --
 10      execute immediate vSQL bulk collect into vResult;
 11      if vResult.count() > 0 then
 12          for i in vResult.first .. vResult.last loop
 13              dbms_output.put_line(vResult(i));
 14          end loop;
 15      end if;
 16  end;
 17  /
1, 3
2, 6
3, 9

PL/SQL procedure successfully completed.