2

I have a table that looks similar to this here:

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

I would like to try and have this output

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
Andrey Morozov
  • 7,839
  • 5
  • 53
  • 75
  • 3
    Please stop posting in all uppercase - it looks like you are shouting at us. And please format your code - I'll do it this time for you. – Frank Schmitt Oct 22 '13 at 07:51
  • possible duplicate of [SQL Server 2005, turn columns into rows](http://stackoverflow.com/questions/428041/sql-server-2005-turn-columns-into-rows) – Frank Schmitt Oct 22 '13 at 07:54
  • Voted for close - the GROUP BY answer in the linked question should work for any RDBMS (doesn't require PIVOT or similar). – Frank Schmitt Oct 22 '13 at 07:55

3 Answers3

0

You can achieve this with a self (outer) join

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'
Mureinik
  • 297,002
  • 52
  • 306
  • 350
0

Try this:

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'

Results:

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


UPDATE

Oracle version (using correlated subqueries instead of cross apply):

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)

Andrey Morozov
  • 7,839
  • 5
  • 53
  • 75
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'
Nitu Bansal
  • 3,826
  • 3
  • 18
  • 24