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 7997077
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T14:52:51+00:00 2026-06-04T14:52:51+00:00

I have audit for records in a table. There multiple columns and each records

  • 0

I have audit for records in a table. There multiple columns and each records states for a change of 1 or more columns.
I need to return an audit result where the return pattern will be: column (id, alias or name), previous value, new value, etc.
The problem is in that there can be multiple columns with changed data per each new record. At the same time the quantity of auditable columns is 5 so it’s possible to “hardcode” there names and changes verifications.

So is it possible to compose such a query in a shortened manner not just using UNIONS and make a SELECT query for each column and check for change?

Let’s say there is the table with the columns:

id, datetime value, int value, varchar value.

And if I have 2 records with such a data change as like:

id1, value1, value1, value1
id1, value2, value1, value2

Then I expect such audit results:

id1, value1 as oldvalue, value2 as newvalue, column2name as columnname
id1, value1 as oldvalue, value2 as newvalue, column4name as columnname
  • 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-06-04T14:52:53+00:00Added an answer on June 4, 2026 at 2:52 pm

    If I haven’t missed anything:

    WITH ranked AS (
      SELECT
        ChangeDate,
        ColPK,
        Col1,
        Col2,
        Col3,
        Col4,
        Col5,
        OverallRank = ROW_NUMBER() OVER (PARTITION BY ColPK       ORDER BY ChangeDate),
        Col1Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col1 ORDER BY ChangeDate),
        Col2Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col2 ORDER BY ChangeDate),
        Col3Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col3 ORDER BY ChangeDate),
        Col4Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col4 ORDER BY ChangeDate),
        Col5Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col5 ORDER BY ChangeDate)
      FROM AuditTable
    )
    , ranked2 AS (
      SELECT
        ChangeDate,
        ColPK,
        Col1,
        Col2,
        Col3,
        Col4,
        Col5,
        Col1Group = RANK() OVER (PARTITION BY ColPK, Col1 ORDER BY OverallRank - Col1Rank),
        Col2Group = RANK() OVER (PARTITION BY ColPK, Col2 ORDER BY OverallRank - Col2Rank),
        Col3Group = RANK() OVER (PARTITION BY ColPK, Col3 ORDER BY OverallRank - Col3Rank),
        Col4Group = RANK() OVER (PARTITION BY ColPK, Col4 ORDER BY OverallRank - Col4Rank),
        Col5Group = RANK() OVER (PARTITION BY ColPK, Col5 ORDER BY OverallRank - Col5Rank),
        Col1Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col1, OverallRank - Col1Rank ORDER BY ChangeDate),
        Col2Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col2, OverallRank - Col2Rank ORDER BY ChangeDate),
        Col3Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col3, OverallRank - Col3Rank ORDER BY ChangeDate),
        Col4Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col4, OverallRank - Col4Rank ORDER BY ChangeDate),
        Col5Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col5, OverallRank - Col5Rank ORDER BY ChangeDate)
      FROM ranked
    ),
    unpivoted AS (
      SELECT
        r.ChangeTime,
        r.ColPK,
        x.ColName,
        ColRank = CASE x.Colname
          WHEN 'Col1' THEN Col1Group
          WHEN 'Col2' THEN Col2Group
          WHEN 'Col3' THEN Col3Group
          WHEN 'Col4' THEN Col4Group
          WHEN 'Col5' THEN Col5Group
        END,
        Value = CASE x.Colname
          WHEN 'Col1' THEN CONVERT(nvarchar(100), r.Col1)
          WHEN 'Col2' THEN CONVERT(nvarchar(100), r.Col2)
          WHEN 'Col3' THEN CONVERT(nvarchar(100), r.Col3)
          WHEN 'Col4' THEN CONVERT(nvarchar(100), r.Col4)
          WHEN 'Col5' THEN CONVERT(nvarchar(100), r.Col5)
        END
      FROM ranked2 r
        INNER JOIN (VALUES ('Col1'), ('Col2'), ('Col3'), ('Col4'), ('Col5')) x (ColName)
          ON x.ColName = 'Col1' AND Col1Rank = 1
          OR x.ColName = 'Col2' AND Col2Rank = 1
          OR x.ColName = 'Col3' AND Col3Rank = 1
          OR x.ColName = 'Col4' AND Col4Rank = 1
          OR x.ColName = 'Col5' AND Col5Rank = 1
    )
    SELECT
      new.ChangeTime,
      new.ColPK,
      new.ColName,
      old.Value AS OldValue,
      new.Value AS NewValue
    FROM unpivoted new
      LEFT JOIN unpivoted old
        ON new.ColPK   = old.ColPK
       AND new.ColName = old.ColName
       AND new.ColRank = old.ColRank + 1
    

    Basically, the idea is to rank contiguous groups of identical values and pick first occurrences of every value. That is done for every column whose values are being audited, and the columns are unpivoted in the process. Afterwards, the unpivoted row set is joined to itself, i.e. for every PK and column name, every row is matched to its predecessor (based on the ranking) to obtain the old value in the same row for the final result set.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

We have a trigger that creates audit records for a table and joins the
I have an audit record table that I am writing to. I am connecting
We have audit columns set by triggers. For obscure security reasons predating my tenure
I have a table called 'Audit' in SQL Server 2005 like this: Name |
I have many domain classes in my application an for Audit logging I need
I have a quick question. I'm have a db an audit Table with a
I have a table with a timestamp column that records when the record is
Say I have some data stored in an audit table, where triggers on the
We have a simple table (an audit log) that our (3rd-party) product fills with
I have a table that could have thousands (millions maybe?) of records. It is

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.