Query to pair interleaved start and end times

情到浓时终转凉″ 提交于 2019-12-23 01:57:06

问题


I need a query to pair interleaved data of 'start' and 'end' times into one neat output, but my main hurdle is with how the data is stored in an interleaved format within the ProcessTimer table.

Input table 1

I have a table called ProcessTimer with three columns.

  • ProcessTimerId INT (PRIMARY KEY)
  • ProcessTimerDatetime DATETIME
  • ProcessTimerAction VARCHAR(5)
  • ProcessId INT (FOREIGN KEY)

'ProcessTimerAction' is only ever set to the value 'START' or 'STOP', which ties in to the 'ProcessTimerDatetime' column, because 'ProcessTimerDatetime' stores a DATETIME value of when a Process has started or stopped.

Each Process is identified via a ProcessId, and that links to another table called Process, which has some details about each Process.

Input table 2

The Process table is set up as follows:

  • ProcessId INT (PRIMARY KEY)
  • ProcessName VARCHAR(255)
  • ProcessOwner VARCHAR(255)

Logically, a Process's START action should always be followed by a STOP action, and display in pairs, however errors in the data mean that there isn't always a STOP action for every START action. In these instances there's nothing I can do but display a NULL for the missing STOP entry

Desired output

I wish to represent the data in grid with the following headings.

  • ProcessOwner
  • ProcessName
  • ProcessStartTime
  • ProcessEndTime

Has anyone achieved something like this before?

I'm unsure how to begin to tackle creating the query I need.

Example data

ProcessTimer table

ProcessTimerId,ProcessTimerDatetime,ProcessTimerAction,ProcessId
1,1/1/2017 08:00:34,START,883
2,1/1/2017 08:03:76,STOP,883
3,1/1/2017 08:03:77,START,445
4,1/1/2017 08:03:79,START,636
5,1/1/2017 08:05:77,STOP,445
6,1/1/2017 08:07:34,START,445
7,1/1/2017 08:09:23,START,445
8,1/1/2017 08:12:61,STOP,636
9,1/1/2017 08:14:65,STOP,445

Process table

ProcessId,ProcessName,ProcessOwner
445,CTC hourlies,Sarah Parkes
636,Garage import,John Dean
883,DF task,Kate Duke

回答1:


Here's one implementation:

WITH ProcessTimerWithRowNum([ProcessId], [ProcessTimerAction], [ProcessTimerDatetime],[rno])
AS
( SELECT [ProcessId],
         [ProcessTimerAction],
         [ProcessTimerDatetime], 
         ROW_NUMBER() OVER(PARTITION BY ProcessId ORDER BY ProcessTimerId) AS [rno] 
  FROM  ProcessTime )

SELECT PT.[ProcessId], 
       P.[ProcessOwner], 
       P.[ProcessName], 
       PT.[ProcessTimerDatetime] AS StartTime, 
       DPT.ProcessTimerDatetime AS EndTime FROM

ProcessTimerWithRowNum PT 

LEFT JOIN

ProcessTimerWithRowNum DPT

ON PT.ProcessId = DPT.ProcessId  AND DPT.ProcessTimerAction = 'STOP' AND DPT.rno = PT.rno + 1

INNER JOIN Process P ON PT.ProcessId = P.ProcessId

WHERE PT.ProcessTimerAction = 'START'

Output for above data:

ProcessOwner | ProcessName | StartTime | EndTime  

445 |Sarah Parkes|  CTC hourlies|   1/1/2017 08:03:77|  1/1/2017 08:05:77

445 |Sarah Parkes|  CTC hourlies|   1/1/2017 08:07:34|  NULL

445 |Sarah Parkes|  CTC hourlies|   1/1/2017 08:09:23|  1/1/2017 08:14:65

636 |John Dean| Garage import|  1/1/2017 08:03:79|  1/1/2017 08:12:61

883 |Kate Duke| DF task|    1/1/2017 08:00:34|  1/1/2017 08:03:76


来源:https://stackoverflow.com/questions/42364642/query-to-pair-interleaved-start-and-end-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!