Home > Enterprise >  Use SQL to add rows to a select statement and join data based upon timestamps
Use SQL to add rows to a select statement and join data based upon timestamps

Time:06-02

So I'm essentially adding an event to a changelog. Presuming I have an initial changelog that looks like this.

changelog table:

id timestamp state
1 10 A
1 20 B
1 30 C
2 10 A
2 20 B

I also have an event table that looks like this:

id timestamp event
1 25 alpha
2 15 alpha

I'm trying to add the rows from the event table to the changelog table so that the end table looks like this

id timestamp state event
1 10 A null
1 20 B null
1 25 B alpha
1 30 C null
2 10 A null
2 15 A alpha
2 20 B null

The difficulty I'm having is on the row I'm adding in I need to fill the state with the state from the row above or row with the most recent timestamp before the timestamp of the row I'm adding. I can't simply use for example the current state.

Is this possible to achieve using SQL?

At the minute I'm just leaving the state null for the added event which isn't what I want.

SELECT 
  *,
  null as event
FROM changelog
UNION
SELECT
  *,
  null as state
FROM event

I'm using PostgreSQL

CodePudding user response:

One option is to merge the two tables using a UNION statement. Then you can translate the null values (with the COALESCE function) in the "state" column with the last "state" value using the LAG window function, which will order on the timestamp for each different id.

WITH cte AS (
    SELECT id, timestamp, state, null AS event FROM changelog_
    UNION
    SELECT id, timestamp, null AS state, event FROM events_
)
SELECT id,
       timestamp,
       COALESCE(state, 
                LAG(state) OVER(PARTITION BY id
                                ORDER     BY timestamp)) AS state,
       event
FROM cte

Try it here.

  • Related