1

我有以下 3 个 Oracle 数据库表:

application (app_id, application_name)      

例如。(1、第一个应用程序)

item_request (app_id, item_id, qty_requested)   

例如。(1, 111, 5), (1, 112, 3), (1, 113, 7)

item (item_id, item_code)

例如。(111, "电脑"), (112, "电话"), (113, "办公桌")

我想制作这张桌子:

new table (app_id, 
           application_name, 
           qty_requested_for_item_with_item_code_111,
           qty_requested_for_item_with_item_code_112,
           qty_requested_for_item_with_item_code_113, 
           etc...)

例如。(1、fistapp、5、3、7等……)

这甚至可能吗?

4

3 回答 3

1

您可以使用动态 SQL 来实现这一点,例如使用 ref 游标。你必须

a)遍历所有现有项目

b)通过添加所有项目来构建您的 SELECT 列表

c) 执行旋转(通过使用 PIVOT 或使用传统的 MAX / CASE / GROUP BY)方法

create table application(app_id number primary key, application_name varchar2(30));
create table item_request(app_id number, item_id number, qty_requested number);
create table item(item_id number primary key, item_code varchar2(30));

insert into application values(1, 'firstapp');
insert into application values(2, 'secondapp');
insert into item values (111, 'Computer');
insert into item values (112, 'Phone');
insert into item values (113, 'Desk');
insert into item_request values (1, 111, 5);
insert into item_request values (1, 112, 3);
insert into item_request values (1, 113, 7);
insert into item_request values (2, 111, 3);

-- SQL/Plus syntax for declaring and using a bind variable of type ref cursor
var x refcursor;

set autoprint on

declare
  l_sql varchar2(4000);
  l_select varchar2(4000);
  l_from varchar2(4000);
begin
  l_select := 'select application.app_id, application.application_name';
  for cur in (select * from item)
    loop
        l_select := l_select || chr(10) || ',max(case when item_code = ''' || cur.item_code || ''' then qty_requested else 0 end) as ' || cur.item_code;
      end loop;
  l_sql := l_select || ' 
    from application 
    left join item_request on application.app_id = item_request.app_id 
    left join item on item.item_id = item_request.item_id
    group by application.app_id, application.application_name';
  dbms_output.put_line(l_sql);
  open :x for l_sql;
end;      
于 2013-09-06T08:28:03.370 回答
1

Oracle 对 Pivot 函数的支持有限。

参见例如http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html

简而言之,对于常规输出,您会遇到一个静态的列列表,您正在转向。

对于动态数据透视表,您可以使用数据透视 xml 函数。但这会在 xml 中生成数据透视列,因此需要解析。

于 2013-09-06T08:05:51.110 回答
0

您可以根据 app_id 申请和项目请求,并根据 itemid 进行数据透视并获取数量。

select * from (select app_id, item_id, qty from application a, item_request ir 
where a.app_id = ir.app_id) pivot(sum(qty) for item_id in (Item List)).

如果 item_id 列表是完整的 item_id 列表,则使用选择查询代替项目列表。

于 2013-09-06T06:17:22.887 回答