Skip to content
Advertisement

Identifying specific changes via audit table

I have an audit table in a SQL database that is structured like the one below:

audit_id id location location_sub location_status dtm_utc_action action_type
2144 2105 9 1 1 2022-09-08 12:36 i
4653 2105 9 1 1 2022-09-08 13:53 u
7304 2105 10 2 2 2022-09-13 15:51 u
7326 2105 11 1 2 2022-09-14 10:06 u

I’m trying to write a query that will assist me in finding records from this table where the location has changed, and would like to show the ID, old location, new location and time of the change.

Based on some other questions, I’ve tried joining the table with itself, but I don’t understand how to prevent duplication. This query below will return each record multiple times, which isn’t desired.

SELECT
    a.id,
    a.location       AS old_loc, 
    a.dtm_utc_action AS FirstModifyDate,
    b.location       AS new_loc, 
    b.dtm_utc_action AS SecondModifyDate  

FROM
    audit_table a
    JOIN audit_table b ON a.id = b.id

WHERE
    a.audit_id <> b.audit_id
    AND
    a.dtm_utc_action < b.dtm_utc_action
    AND
    a.location <> b.location
    AND
    a.id = '2105'

Would like results to look like this:

id old_loc new_loc dtm_utc_action
2105 9 10 2022-09-13 15:50
2105 10 11 2022-09-14 10:06

Advertisement

Answer

Depending on your DBMS you can use a LEAD function to retrieve the next date from the audit table

with audit_sequence as (
    select *, lead(dtm_utc_action) OVER ( PARTITION BY id ORDER BY dtm_utc_action) next_update
    from audit_table 
) 

SELECT
    a.id,
    a.location       AS old_loc, 
    a.dtm_utc_action AS FirstModifyDate,
    b.location       AS new_loc, 
    b.dtm_utc_action AS SecondModifyDate  

FROM
    audit_table a
    JOIN audit_sequence s on a.id = s.id and a.dtm_utc_action = s.dtm_utc_action
    JOIN audit_table b on a.id = b.id and b.dtm_utc_action = s.next_update
WHERE
    a.location <> b.location
    AND
    a.id = '2105'
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement