简体   繁体   中英

How to track changes in records in SQL Server?

I have the following table which has tracking records of all students.

|==========================================|
| ID      |  Department     | Date         |
|==========================================|
| 001     | English         | Feb 3 2017   |
| 001     | English         | Feb 4 2017   |
| 001     | Science         | Mar 1 2017   |
| 001     | Science         | Apr 2 2017   |
| 001     | Maths           | Apr 7 2017   |
| 002     | Maths           | Feb 1 2017   |
| 002     | Maths           | Apr 7 2017   |
| 003     | Maths           | Apr 3 2017   |
| 004     | Science         | Feb 1 2017   |
| 004     | Maths           | Apr 7 2017   |
|==========================================| 

I need to fetch the previous record just before when the student has changed the department. For the example above, the record set returned should be

For 001,

| 001     | English         | Feb 4 2017   |
| 001     | Science         | Apr 2 2017   |

For 002 and 003

No changes

For 004

| 004     | Science         | Feb 1 2017   |

There is also a possibility that the same user can change back to the same department. for example, user001 can change from dept a to dept b to dept c and back to dept a. I have read about T-SQL send and receive. But not sure if that would help in this scenario. Please help.

One way to do it is to use ROW_NUMBER function with partitioning to detect when the value of the Department column changes.

Sample data

DECLARE @T TABLE (ID int, Department nvarchar(100), dt date);
INSERT INTO @T (ID, Department, dt) VALUES
(1, 'English', 'Feb 3 2017'),
(1, 'English', 'Feb 4 2017'),
(1, 'Science', 'Mar 1 2017'),
(1, 'Science', 'Apr 2 2017'),
(1, 'Maths  ', 'Apr 7 2017'),
(2, 'Maths  ', 'Feb 1 2017'),
(2, 'Maths  ', 'Apr 7 2017'),
(3, 'Maths  ', 'Apr 3 2017'),
(4, 'Science', 'Feb 1 2017'),
(4, 'Maths  ', 'Apr 7 2017');

Query

WITH
CTE
AS
(
    SELECT
        ID
        ,Department
        ,dt
        ,ROW_NUMBER() OVER (PARTITION BY ID, Department ORDER BY dt DESC) AS rnPart
        ,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY dt DESC) AS rnID
    FROM @T
)
SELECT
    ID
    ,Department
    ,dt
FROM CTE
WHERE
    rnPart = 1
    AND rnID <> 1
ORDER BY
    ID
    ,dt
;

Result

+----+------------+------------+
| ID | Department |     dt     |
+----+------------+------------+
|  1 | English    | 2017-02-04 |
|  1 | Science    | 2017-04-02 |
|  4 | Science    | 2017-02-01 |
+----+------------+------------+

This can be done by creating after insert/update trigger on the tables that you need to track. Using the logical tables Inserted/Deleted in sql server you can track the newly inserted and modified fields on a table.

Inserted (Logical table):It'll give you the details of the newly inserted records/updated values (column values).

Deleted(Logical Table): It'll give you the old value of a field before it got modified/deleted.

I'm not that sure about it but you can get help with the concept of stored procedures. They are functions which are a part of database. You can set the display when you make the query

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