gpt4 book ai didi

sql - UNPIVOT 在不确定的列数上

转载 作者:行者123 更新时间:2023-12-04 21:32:09 25 4
gpt4 key购买 nike

如何编写一个查询,将始终具有 1 行和多列的表取消透视到具有 2 列的结果集:column_name 和 value。我知道表格的底层结构是真正的问题所在,但我无法改变这一点。此查询也必须不知道所述表中的名称和/或列数,因为经常添加列(再次,我知道,糟糕的设计,无法更改),我不想要每次添加新列时都必须更新查询。我已经能够使用 unpivot 完成一些接近的事情,但是该查询需要对列名进行硬编码。

这可能吗?

Oracle 11gR2

最佳答案

听起来您想取消透视表(透视需要从多行 2 列变为 1 行多列)。您很可能需要使用动态 SQL 来生成查询,然后使用 DBMS_SQL 包(或可能是 EXECUTE IMMEDIATE)来执行它。您还应该能够构造一个执行逆透视的流水线表函数。您还需要在管道表函数中使用动态 SQL,但它可能会减少代码。不过,我希望使用 UNPIVOT 的纯动态 SQL 语句更有效。

一种低效但相对容易遵循的方法,例如

SQL> ed
Wrote file afiedt.buf

1 create or replace type emp_unpivot_type
2 as object (
3 empno number,
4 col varchar2(4000)
5* );
SQL> /

Type created.

SQL> create or replace type emp_unpivot_tbl
2 as table of emp_unpivot_type;
3 /

Type created.

SQL> ed
Wrote file afiedt.buf

1 create or replace function unpivot_emp
2 ( p_empno in number )
3 return emp_unpivot_tbl
4 pipelined
5 is
6 l_val varchar2(4000);
7 begin
8 for cols in (select column_name from user_tab_columns where table_name = 'EMP')
9 loop
10 execute immediate 'select ' || cols.column_name || ' from emp where empno = :empno'
11 into l_val
12 using p_empno;
13 pipe row( emp_unpivot_type( p_empno, l_val ));
14 end loop;
15 return;
16* end;
SQL> /

Function created.

然后您可以在 SQL 语句中调用它(我认为您至少需要第三列带有列名)

SQL> ed
Wrote file afiedt.buf

1 select *
2* from table( unpivot_emp( 7934 ))
SQL> /

EMPNO COL
---------- ----------------------------------------
7934 7934
7934 MILLER
7934 CLERK
7934 7782
7934 23-JAN-82
7934 1301
7934
7934 10

8 rows selected.

更有效的方法是改编 Tom Kyte 的 show_table pipelined table function .

关于sql - UNPIVOT 在不确定的列数上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15100101/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com