Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6693969
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T06:02:51+00:00 2026-05-26T06:02:51+00:00

I need to create a process that will extract the changes from a table

  • 0

I need to create a process that will extract the changes from a table where each row is a snapshot of a row in another table. The real-world problem involves many tables with many fields, but as a simple example, suppose that I have the following snapshot data:

Sequence    DateTaken      ID       Field1    Field2
--------    -----------    ----     ------    ------
       1    '2011-01-01'      1     'Red'          2
       2    '2011-01-01'      2     'Blue'        10
       3    '2011-02-01'      1     'Green'        2
       4    '2011-03-01'      1     'Green'        3
       5    '2011-03-01'      2     'Purple'       2
       6    '2011-04-01'      1     'Yellow'       2

The Sequence and DateTaken fields relate directly to the snapshot table itself. The ID field is the primary key of the source table and Field1 and Field2 are other fields in the same (source) table.

I can get part-way to a solution with a query like this:

WITH Snapshots (Sequence, DateTaken, ID, Field1, Field2, _Index)
AS
(
    SELECT Sequence, DateTaken, ID, Field1, Field2, ROW_NUMBER() OVER (ORDER BY ID, Sequence) _Index
    FROM #Snapshots
)
SELECT
      c.DateTaken, c.ID
    , c.Field1 Field1_Current, p.Field1 Field1_Previous, CASE WHEN c.Field1 = p.Field1 THEN 0 ELSE 1 END Field1_Changed
    , c.Field2 Field2_Current, p.Field2 Field2_Previous, CASE WHEN c.Field2 = p.Field2 THEN 0 ELSE 1 END Field2_Changed
FROM Snapshots c
JOIN Snapshots p ON p.ID = c.ID AND (p._Index + 1) = c._Index
ORDER BY c.Sequence DESC

The above query will identify what is changing from one snapshot to the next, but it is still not in the form that I need. Each row in the output may contain several changes. At the end of the day, I need one row per change that identifies what field was changed, along with its previous/current values. Fields that have not actually changed will need to be excluded from the final output. So if the above query output is like this:

DateTaken   ID  Field1_Current  Field1_Previous  Field1_Changed  Field2_Current  Field2_Previous  Field2_Changed
----------  --  --------------  ---------------  --------------  --------------  ---------------  --------------
2011-04-01  1   Yellow          Green            1               2               3                1
2011-02-01  1   Green           Red              1               2               2                0

I need to transform that into something like this:

DateTaken   ID  Field    Previous   Current
----------  --  -------  --------   ---------
2011-04-01  1   Field1   Green      Yellow
2011-04-01  1   Field2   3          2
2011-02-01  1   Field1   Red        Green

I thought I might be able to get there with UNPIVOT, but I’ve not been able to make that work. I consider any solution involving cursors or similar to be an absolute last resort.

Thanks much for any advice.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T06:02:52+00:00Added an answer on May 26, 2026 at 6:02 am

    Here’s a working sample that uses UNPIVOT. It’s based on my answer to my question Better way to Partially UNPIVOT in Pairs in SQL

    This has some nice features.

    1. Adding additional fields is easy. Just add values to the SELECT and UNPIVOT clause. You don’t have to add additional UNION clauses

    2. The where clause WHERE curr.value <> prev.value never changes regardless of how many fields are added.

    3. The performance is surprisingly fast.

    4. Its portable to Current versions of Oracle if you need that


    SQL

    Declare @Snapshots as table(
    Sequence int,
    DateTaken      datetime,
    [id] int,
    field1 varchar(20),
    field2 int)
    
    
    
    INSERT INTO @Snapshots VALUES 
    
          (1,    '2011-01-01',      1,     'Red',          2),
          (2,    '2011-01-01',      2,     'Blue',        10),
          (3,    '2011-02-01',      1,     'Green',        2),
          (4,    '2011-03-01',      1,     'Green' ,       3),
          (5,    '2011-03-01',      2,     'Purple',       2),
          (6,    '2011-04-01',      1,     'Yellow',       2)
    
    ;WITH Snapshots (Sequence, DateTaken, ID, Field1, Field2, _Index)
    AS
    (
        SELECT Sequence, DateTaken, ID, Field1, Field2, ROW_NUMBER() OVER (ORDER BY ID, Sequence) _Index
        FROM @Snapshots
    )
    ,  data as(
    SELECT
         c._Index
        , c.DateTaken
        ,  c.ID
        , cast(c.Field1  as varchar(max)) Field1
        , cast(p.Field1  as varchar(max))Field1_Previous
        , cast(c.Field2   as varchar(max))Field2
        , cast(p.Field2  as varchar(max)) Field2_Previous 
    
    
    FROM Snapshots c
    JOIN Snapshots p ON p.ID = c.ID AND (p._Index + 1) = c._Index
    )
    
    
    , fieldsToRows 
         AS (SELECT DateTaken, 
                    id,
                    _Index,
                    value,
                    field
    
             FROM   data p UNPIVOT (value FOR field IN (field1, field1_previous, 
                                                            field2, field2_previous) ) 
                    AS unpvt
            ) 
    SELECT 
        curr.DateTaken,
        curr.ID,
        curr.field,
        prev.value previous,
        curr.value 'current'
    
    FROM 
            fieldsToRows curr 
            INNER  JOIN  fieldsToRows prev
            ON curr.ID = prev.id
                AND curr._Index = prev._Index 
                AND curr.field + '_Previous' = prev.field
    WHERE 
        curr.value <> prev.value
    

    Output

    DateTaken               ID          field     previous current
    ----------------------- ----------- --------- -------- -------
    2011-02-01 00:00:00.000 1           Field1    Red      Green
    2011-03-01 00:00:00.000 1           Field2    2        3
    2011-04-01 00:00:00.000 1           Field1    Green    Yellow
    2011-04-01 00:00:00.000 1           Field2    3        2
    2011-03-01 00:00:00.000 2           Field1    Blue     Purple
    2011-03-01 00:00:00.000 2           Field2    10       2
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need to create daemon that will monitor certain directory and will process every
I need to create an out-of-process COM server (.exe) in C# that will be
I need to create an automated process (preferably using Java) that will: Open browser
I need to create a background process that will wait for incoming commands and
I need to create a process with integrity level high, so that it can
I have a need to create a transactional process using an external API that
Need to create a class that will do all things as the merge function.
I need to create a mule service that will POST data to a web
My Case: I'm working on a system that will need to create various X12
I want to create a timesheet application where I need an application that will

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.