I have a table that contains user actions based on dates. The table is used as a timeline of events. The following example shows how two people changed their job roles through time:
DECLARE @tbl TABLE (
UserID int,
ActionID int,
ActionDesc nvarchar(50),
ActionDate datetime
);
INSERT INTO @tbl (UserID, ActionID, ActionDesc, ActionDate)
VALUES
-- First person
(1, 200, 'Promoted', '2000-01-01'),
(1, 200, 'Promoted', '2001-01-01'),
(1, 200, 'Promoted', '2002-02-01'),
(1, 300, 'Moved', '2004-03-01'),
(1, 200, 'Promoted', '2005-03-01'),
(1, 200, 'Promoted', '2006-03-01'),
-- Second person
(2, 200, 'Promoted', '2006-01-01'),
(2, 300, 'Moved', '2007-01-01'),
(2, 200, 'Promoted', '2008-01-01');
SELECT * FROM @tbl ORDER BY UserID, ActionDate DESC;
This gives the following, shown as the most recent event first:
I need to show the table in reverse date order, but remove any events that occur directly after they have already just occured, based on a [UserID/ActionID] match. For example, if the person was promoted, and then promoted again straight after this, the second promotion would not be included in the results, because it would be considered a duplicate of the previous action.
The desired output therefore, is:
Following research, I tried to get ROW_NUMBER() to identify the duplicates:
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY UserID, ActionID ORDER BY ActionDate ASC) AS RowNum
FROM
@tbl
ORDER BY
UserID, ActionDate DESC;
...But it doesn't quite work, as the numbering is not reset after each different action. I might be over-thinking this, but am struggling for inspiration because search results are returning the myriad of questions where people are simply removing duplicates from lists.


