简体   繁体   中英

SQL - Get difference on dates based on same column from different rows

I have a table where it's stored all updates on form fields. I'm trying to build a query where I want to calculate how many time has elapsed between each update.

Here is an example of my table:

ticket,last_update,status
12345,2019-03-29 13:54:55.000000,canceled
12345,2019-03-29 12:46:20.000000,analysis
12345,2019-03-28 18:30:55.000000,canceled
12345,2019-03-28 09:31:20.000000,analysis

I want to check the diff time on status change between analysis to other statuses (each analysis has a subsequent status).

Example output:

First analysis: differente between analysis 2019-03-28 09:31:20.000000 and 2019-03-28 18:30:55.000000 canceled
First analysis: differente between analysis 2019-03-29 12:46:20.000000 and 2019-03-29 13:54:55.000000 canceled

Is possible to write a SQL statement to return this data? I'm stuck on this statement:

select ticket, last_update, status from history as h
where h.ticket = 12345
  and h.field = 'custom_field_a';

I would like to avoid write some code on backend to perform it.

Tried it using PARTITION BY:

select ticket,
       last_update - lag(last_update) over (partition by ticket order by last_update) as difference
from history as h
where h.ticket = 12345
  and h.field = 'custom_field_a'
group by ticket, last_update;

It should return 2 rows containing difference against analysis -> canceled, analysis -> canceled but i got 4 rows.

You are able to use the LAG functionality, which takes the data from the previous row. This query below should be able to calculate the difference:

 SELECT last_update - lag(last_update) over (order by last_update) as difference
        FROM history AS h
        where h.ticket = 12345
              and h.field = 'custom_field_a';

/A

You can do something like this:

select ticket,
       max(last_update) filter (where status = 'created') as created_ts,
       max(last_update) filter (where status = 'cancelled') as cancelled_ts,
       max(last_update) filter (where status = 'analysis') as analysis_ts,
from history as h
where h.ticket = 12345 and
      h.field = 'custom_field_a'
group by ticket;

I'm not sure how you want the differences expressed, but you can just subtract the relevant values.

You can join the relevant lines, like so:

  select created.ticket
       , created.last_update as created_ts
       , analysis.last_update as analysis_ts
       , canceled.last_update as canceled_ts
    from history as created
    left join history as analysis
      on created.ticket = analysis.ticket
     and created.field = analysis.field
     and analysis.status = 'analysis'
    left join history as canceled
      on created.ticket = canceled.ticket
     and created.field = canceled.field
     and canceled.status = 'canceled'
   where created.ticket = 12345
     and created.field = 'custom_field_a'
     and created.status = 'created'

Not sure how field plays into it, it's probably a join condition on all joins as well. This will work if you have one entry per status, otherwise you'll get duplicate rows and might need a different strategy.

You will want to use the lag() window function to get the time difference between the two

https://www.postgresql.org/docs/current/functions-window.html

Edit you may want to use a CTE to filter your query first for the result you want.

with history_set as(
    select
        ticket,
        lag(last_update)
            over (partition by ticket order by last_update) as prev_update,
        last_update,
        last_update - lag(last_update)
        over (partition by ticket order by last_update) as time_diff,
        status
     from history as h
    where h.ticket = 12345
      and h.field = 'custom_field_a'
    order by last_update
)
select
    ticket,
    prev_update,
    last_update,
    time_diff,
    status
from history_set
where status <> 'analysis'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM