我的公司将Log_Info存储在一个表中,其中包含工厂ID,部门ID,日志日期,日志时间,带计数器值的日志分钟。请帮助我如何将[Log hour + Log min]转换为列,如本例所示,使用Oracle Database 10g 10.2版中的PL / SQL。
非常感谢。
答案 0 :(得分:0)
我会告诉你使用PIVOT,这是一种非常简单的本地做这种事情的方法,但不幸的是我相信这是在11g中引入的。据我所知,你有两种选择;如果要保留本机SQL,则必须使用硬编码的case语句。否则,此解决方案可能对您有用..
declare v_str varchar2(2000);
begin
v_str:='select factoryid,deptid,logdate';
for i in (select distinct 'H'||loghour||'_'||logmin a from test_table order by a) loop
v_str:=v_str||',max(case ''H''||loghour||''_''||logmin when '''||i.a||''' then counter end) as "'||i.a||'"';
end loop;
v_str:=v_str||' from test_table group by factoryid,deptid,logdate order by factoryid';
DBMS_OUTPUT.PUT_LINE(v_str);
end;
这将为您提供一个动态查询,然后您可以在循环或结果集中执行,无论您选择什么(而不是我在这里的PUT_LINE)。根据您提供的当前数据,此块的结果是:
select factoryid,deptid,logdate,
max(case 'H'||loghour||'_'||logmin when 'H0_0' then counter end) as "H0_0",
max(case 'H'||loghour||'_'||logmin when 'H0_30' then counter end) as "H0_30",
max(case 'H'||loghour||'_'||logmin when 'H1_0' then counter end) as "H1_0",
max(case 'H'||loghour||'_'||logmin when 'H1_30' then counter end) as "H1_30",
max(case 'H'||loghour||'_'||logmin when 'H2_0' then counter end) as "H2_0"
from test_table
group by factoryid,deptid,logdate order by factoryid
它将为您提供您正在寻找的内容。
编辑:作为一个注释,包括MAX以消除case语句中的所有内容。这假设每个工厂ID / deptid / logdate每次只有一个计数器值。
如果你想去原生路线并且有一个定义的loghour和logmin列表(不是100%肯定,但看起来你会从H0_0到H23_30),你可以使用查询PL / SQL块在上面吐出,并继续创建case语句,直到考虑所有loghours和logmins。如果是这种情况并且loghour / min具有已定义的范围,则应该执行此操作,因为在动态SQL上使用本机SQL具有性能优势,例如游标缓存。