我必须编写一个查询,如下所示。我试过但不能写。请帮帮我。
我有一个返回结果集的表。
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
中答案 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.