日期:2014-05-17  浏览次数:20992 次

请教Oracle依时间顺序分组 并行转列
id            date    
步骤3     11/17 00:00
步骤1     11/17 01:00
步骤2     11/17 02:00
步骤3     11/17 03:00
步骤1     11/17 04:00
步骤2     11/17 05:00
步骤3     11/17 06:00

原始数据如以上所示,想要得到这样的结果:

序号   步骤1          步骤2         步骤3
1    11/17 01:00  11/17 02:00    11/17 03:00
2    11/17 04:00  11/17 05:00    11/17 06:00

如何通过sql取得这样的结果?
------最佳解决方案--------------------
with test as ( 
SELECT 'bz3' as id,'11/17 00:00' AS dateD from dual 
union all
SELECT 'bz1' as id,'11/17 01:00' AS dateD from dual 
union all
SELECT 'bz2' as id,'11/17 02:00' AS dateD from dual 
union all
SELECT 'bz3' as id,'11/17 03:00' AS dateD from dual 
union all
SELECT 'bz1' as id,'11/17 04:00' AS dateD from dual 
union all
SELECT 'bz2' as id,'11/17 05:00' AS dateD from dual 
union all
SELECT 'bz3' as id,'11/17 06:00' AS dateD from dual 
union all
SELECT 'bz1' as id,'11/17 07:00' AS dateD from dual 
)
select *
  from (select max(decode(ID, 'bz1', dateD, '')) as str1,
               max(decode(ID, 'bz2', dateD, '')) as str2,
               max(decode(ID, 'bz3', dateD, '')) as str3
          from (select row_number() over(order by dateD) - regexp_substr(id, '\d+') as rn,
                       ID,
                       dateD
                  from test)
         group by rn)
 where str1 is not null
   and str2 is not null
   and str2 is not null


--------------------------------------------
1 11/17 01:00 11/17 02:00 11/17 03:00
2 11/17 04:00 11/17 05:00 11/17 06:00

偷懒啦。
------其他解决方案--------------------
弟弟,你要仔细研究一下3楼的sql,应该满足你的需求的
即使有偏差,改动也不大。


row_number() over(order by dateD)  --按照时间排序
regexp_substr(id, '\d+') --截取 步骤1 步骤2 步骤3 后面的 1,2,3 这三个数字

--两者相减,得到的结果 既可以达到你想要的分组目的
--仔细