将多行数据转换为单行

时间:2013-10-22 07:50:28

标签: sql oracle

我有一张类似于此处的表格:

DOCCODE  |  DOCDATE  |  STATUS    
001      | 10-OCT-13 |  START    
001      | 12-OCT-13 |  STOP    
001      | 15-OCT-13 |  START    
001      | 20-OCT-13 |  STOP    
002      | 01-NOV-13 |  START

我想尝试输出

DOCCODE   | STARTDATE  |  STOPDATE  | STATUS    
001       | 10-OCT-13  |  12-OCT-13 | STOP    
001       | 15-OCT-13  |  20-OCT-13 | STOP    
002       | 01-NOV-13  |            | START

3 个答案:

答案 0 :(得分:0)

您可以通过自我(外部)联接实现此目的

SELECT start.doccode AS doccode, 
       start.docdate AS startdate, 
       stop.docdate AS stopdate, 
       COALESCE(stop.status, start.status) AS status
FROM   my_table start
LEFT OUTER JOIN my_table stop ON start.doccode = stop.doccode
WHERE  start.doccode = 'START' AND stop.doccode = 'STOP'

答案 1 :(得分:0)

试试这个:

select sr.DOCCODE
, sr.DOCDATE [STARTDATE]
, x.DOCDATE [STOPDATE]
, ISNULL(x.[STATUS], sr.[STATUS]) [STATUS]
from my_table sr
outer apply (
    select top 1 *
    from my_table sp
    where [STATUS] = 'STOP'
    and DOCDATE > sr.DOCDATE
    and DOCCODE = sr.DOCCODE
    order by DOCDATE) x
where sr.[STATUS]  = 'START'

结果:

DOCCODE STARTDATE   STOPDATE    STATUS
001     2013-10-10  2013-10-12  STOP
001     2013-10-15  2013-10-20  STOP
002     2013-11-01  NULL        START

SQL Fiddle


更新

Oracle版本(使用相关子查询而不是交叉应用):

select sr.DOCCODE
, sr.DOCDATE STARTDATE
, (
    select min(DOCDATE)
    from my_table sp
    where STATUS = 'STOP'
    and DOCDATE > sr.DOCDATE
    and DOCCODE = sr.DOCCODE) as STOPDATE
, NVL((
    select min(STATUS)
    from my_table sp
    where STATUS = 'STOP'
    and DOCDATE > sr.DOCDATE
    and DOCCODE = sr.DOCCODE), sr.STATUS) as STATUS
from my_table sr
where sr.STATUS  = 'START'

SQL Fiddle (Oracle)

答案 2 :(得分:0)

SELECT s1.doccode AS doccode, 
   s1.docdate AS startdate, 
   s2.docdate AS stopdate, 
   isnull(s2.status, s1.status) AS status
FROM   my_table s1
LEFT OUTER JOIN my_table s2 ON s1.doccode = s2.doccode
WHERE  s1.doccode = 'START' AND s2.doccode = 'STOP'