100分求一个数据库查询语句(ORACLE 11g)
一张表tabl1 如下:
epqname createtime endtime
设备1 2014.10.01 11:00:00 2014.10.01 13:22:00
设备2 2014.10.27 11:00:00 2014.10.27 14:10:00
设备3 2014.11.11 14:00:00 2014.11.11 15:00:00
设备4 2014.11.29 11:00:00 2014.11.29 16:00:00
我想查询出来结果,显示出,每个设备每天运转的小时数,不足1小时的,算1小时(1小时25分,1小时10分钟 都算2小时)
将日期作为列名,显示当天运转的时间。
epqname 2014.10.01 2014.10.27 2014.11.11 2014.11.29
设备1 3 0 0 0
设备2 0 4 0 0
设备3 0 0 1 0
设备4 0 0 0 5
------解决思路----------------------
本帖最后由 bw555 于 2014-11-27 11:12:47 编辑
先给你写一个不跨天的情况
with T AS (
SELECT epqname,TRUNC(createtime) D,CEIL((ENDTIME-createtime) *24) AS S
FROM tabl1)
SELECT epqname,
SUM(DECODE(D,TO_DATE('2014.10.01','YYYY.MM.DD'),S)) AS "2014.10.01",
SUM(DECODE(D,TO_DATE('2014.10.27','YYYY.MM.DD'),S)) AS "2014.10.27",
SUM(DECODE(D,TO_DATE('2014.11.11','YYYY.MM.DD'),S)) AS "2014.11.11",
SUM(DECODE(D,TO_DATE('2014.11.29','YYYY.MM.DD'),S)) AS "2014.11.29"
FROM T
GROUP BY epqname
------解决思路----------------------
如果你的createtime和endtime是date类型的话(如果不是要用to_date转化一下数据类型),借鉴下面代码。
select epqname,
sum(case when to_char(t.createtime,'yyyy.mm.dd')='2014.10.01'
then ceil((t.endtime-t.createtime)*24) else 0 end) "2014.10.01",
sum(case when to_char(t.createtime,'yyyy.mm.dd')='2014.10.27'
then ceil((t.endtime-t.createtime)*24) else 0 end) "2014.10.27",
sum(case when to_char(t.createtime,'yyyy.mm.dd')='2014.11.11'
then ceil((t.endtime-t.createtime)*24) else 0 end) "2014.11.11",
sum(case when to_char(t.createtime,'yyyy.mm.dd')='2014.11.29'
then ceil((t.endtime-t.createtime)*24) else 0 end) "2014.11.29"
from tabl1 t
group by epqname
order by epqname;
------解决思路----------------------
一、不确定列直接查询是没办法实现的提供两个方案
1、动态拼接sql语句,然后生成视图,然后select * from 视图
2、动态拼接sql语句,利用游标,将结果循环打印输出
二、存在跨天的情况,需要进行拆分
用下面的语句的查询结果代替原表,未测试,你先执行下看看效果吧
select epqname,
greatest(trunc(createtime)+level-1,createtime) createtime,
least(trunc(createtime)+level,endtime) endtime
from tabl1
connect by trunc(createtime)+level-1<=trunc(endtime)
and rowid=prior rowid
and prior dbms_random.value is not null
------解决思路----------------------
动态行转不定列的方法,在9#已经说明,采用视图实现的方式可以参考下面链接,大同小异
参考3#固定列数的sql写法,拼接sql语句,然后动态创建视图,然后select * from 视图
oracle行转列(动态行转不定列)
目前的oracle版本里没有任何可以直接的行转动态列方法,只能借助视图、游标之类的工具间接实现
如果从xml中select 可以借助pivot any的写法实现