Sql oracle:动态列名
可能重复:Sql oracle:动态列名,sql,oracle,oracle10g,pivot,Sql,Oracle,Oracle10g,Pivot,可能重复: 我真正的问题就是这样,但有许多表相互关联。所以,我刚刚创建了一个例子,假设这个问题解决了,我真正的问题就解决了。 这是我的桌子: tbl_产品 tp_id | tp_name 1 apple 2 mango 3 pineapple ts_id | ts_location | ts_tp_id | ts_sales 1 NY 2
我真正的问题就是这样,但有许多表相互关联。所以,我刚刚创建了一个例子,假设这个问题解决了,我真正的问题就解决了。 这是我的桌子: tbl_产品
tp_id | tp_name
1 apple
2 mango
3 pineapple
ts_id | ts_location | ts_tp_id | ts_sales
1 NY 2 5
2 LN 2 10
3 QL 1 25
4 QL 3 20
5 LN 3 35
6 NY 3 50
7 NY 1 100
tbl_销售
tp_id | tp_name
1 apple
2 mango
3 pineapple
ts_id | ts_location | ts_tp_id | ts_sales
1 NY 2 5
2 LN 2 10
3 QL 1 25
4 QL 3 20
5 LN 3 35
6 NY 3 50
7 NY 1 100
如果我有这两个表,tbl_products和tbl_sales,那么如何创建具有如下动态列的查询:
sales_location | apple | mango | pineapple
NY 100 5 50
由于您使用的是Oracle10g,苹果、芒果和菠萝的销售总额应根据位置而定,因此没有
PIVOT
函数,因此您必须使用带有CASE
语句的聚合函数来执行这种类型的转换
如果提前知道这些值,则可以在静态版本中对其进行硬编码:
select s.ts_location,
sum(case when p.tp_name = 'apple' then s.ts_sales else 0 end) Apple,
sum(case when p.tp_name = 'mango' then s.ts_sales else 0 end) Mango,
sum(case when p.tp_name = 'pineapple' then s.ts_sales else 0 end) Pineapple
from tbl_sales s
inner join tbl_products p
on s.ts_tp_id = p.tp_id
group by s.ts_location
看
但是,如果您的值事先不知道,那么您必须实现动态sql,并且在Oracle中,您需要使用以下过程:
CREATE OR REPLACE procedure dynamic_pivot(p_cursor in out sys_refcursor)
as
sql_query varchar2(1000) := 'select s.ts_location ';
begin
for x in (select distinct tp_name from tbl_products order by 1)
loop
sql_query := sql_query ||
' , sum(case when p.tp_name = '''||x.tp_name||''' then s.ts_sales end) as '||x.tp_name;
dbms_output.put_line(sql_query);
end loop;
sql_query := sql_query || ' from tbl_sales s
inner join tbl_products p
on s.ts_tp_id = p.tp_id
group by s.ts_location';
dbms_output.put_line(sql_query);
open p_cursor for sql_query;
end;
/
然后返回您可以使用的结果(注意:我在Toad中就是这样做的):
两者都将返回结果:
| TS_LOCATION | APPLE | MANGO | PINEAPPLE |
-------------------------------------------
| LN | 0 | 10 | 35 |
| QL | 25 | 0 | 20 |
| NY | 100 | 5 | 50 |
@hsuk对于苹果来说应该是100对吗?@bluefeet Oracle数据库10g企业版10.2.0.1.0-Prod@SRIRAM:是的,更正了别名:选择1作为“MY_COL1”,选择“x”作为“MY_COL2”等等……我不知道主持人为什么要结束这个问题。我认为这个问题不可能与你们提到的问题重复。它在意义上完全不同,我需要动态列。(列数不是固定的)。在另一个问题上,你们可以看到解决方案是在途中制定的,列总是固定的。解决方案具有手动输入列的功能。是否可以不创建存储过程?是否有打印生成的动态查询的方法?如果需要光标,我应该为x提供什么值?