Find last two updates to a record


/ Published in: MySQL
Save to your folder(s)

Created as reply to question on ittoolbox.com:"Need your help in writing a query to pull audit history i.e. Last updated by a user 'XYZ' and for the same record key (ID) the second last record in the audit history table. i.e. Last update by this user and the previous updated record to this record by anybody e.g. "
http://database.ittoolbox.com/groups/technical-functional/sql-l/sql-to-find-records-updated-by-particular-user-and-the-prior-one-5732386

This snippet is written to show a step-by-step process of building the query to produce the results. It started with the simple query, then builds on that to the final query and results.


Copy this code and paste it in your HTML
  1. -- Let's restate the problem and solve it in pieces. Then put the pieces together.
  2.  
  3. -- CREATE THE DATA
  4.  
  5. create table theTable (
  6. id int,
  7. updated_by varchar(20),
  8. update_date date
  9. );
  10. insert into theTable (id, updated_by, update_date) VALUES (1,"XYZ",DATE "2015-05-11");
  11. insert into theTable (id, updated_by, update_date) VALUES (1,"ABC",DATE "2015-05-10");
  12. insert into theTable (id, updated_by, update_date) VALUES (1,"CDE",DATE "2015-05-09");
  13. insert into theTable (id, updated_by, update_date) VALUES (2,"ABC",DATE "2015-05-11");
  14. insert into theTable (id, updated_by, update_date) VALUES (2,"XYZ",DATE "2015-05-10");
  15. insert into theTable (id, updated_by, update_date) VALUES (3,"XYZ",DATE "2015-05-11");
  16. insert into theTable (id, updated_by, update_date) VALUES (3,"XYZ",DATE "2015-05-10");
  17. insert into theTable (id, updated_by, update_date) VALUES (3,"CDE",DATE "2015-05-09");
  18.  
  19. -- WHAT'S IN THE TABLE?
  20.  
  21. select id, updated_by, update_date from theTable;
  22.  
  23. -- (1) WHEN WAS EACH ROW MOST RECENTLY UPDATED?
  24.  
  25. select id, max(update_date) as "max_update_date"
  26. from theTable
  27.  
  28. -- (2) WHO MADE THAT UPDATE?
  29.  
  30. select id, updated_by, update_date
  31. from theTable
  32. where (id, update_date) in (
  33. select id, max(update_date) as "max_update_date"
  34. from theTable
  35. );
  36.  
  37. -- (3) WHEN WERE ALL THE PREVIOUS UPDATES FOR THAT ROW?
  38.  
  39. select secondUpdate.id, secondUpdate.update_date
  40. from theTable secondUpdate
  41. select id, max(update_date) as "max_update_date"
  42. from theTable
  43. ) lastUpdate
  44. on secondUpdate.id = lastUpdate.id
  45. and secondUpdate.update_date < lastUpdate.max_update_date
  46. ;
  47.  
  48. -- (4) WHAT'S THE MOST RECENT OF THOSE PREVIOUS UPDATES?
  49.  
  50. select secondUpdate.id, max(secondUpdate.update_date) max_previous_date
  51. from theTable secondUpdate
  52. select id, max(update_date) as "max_update_date"
  53. from theTable
  54. ) lastUpdate
  55. on secondUpdate.id = lastUpdate.id
  56. and secondUpdate.update_date < lastUpdate.max_update_date
  57. group by secondUpdate.id;
  58.  
  59. -- (5) WHO MADE THAT LAST PREVIOUS UPDATE?
  60.  
  61. select T.id,T.updated_by, T.update_date
  62. from theTable T
  63. select secondUpdate.id, max(secondUpdate.update_date) max_previous_date
  64. from theTable secondUpdate
  65. select id, max(update_date) as "max_update_date"
  66. from theTable
  67. ) lastUpdate
  68. on secondUpdate.id = lastUpdate.id
  69. and secondUpdate.update_date < lastUpdate.max_update_date
  70. group by secondUpdate.id
  71. ) lastPreviousUpdate
  72. on T.id = lastPreviousUpdate.id
  73. and T.update_date = lastPreviousUpdate.max_previous_date
  74. ;
  75.  
  76. -- (6) NOW GET BOTH OF THEM
  77.  
  78. select L.id "Record", L.updated_by "lastUpdater", L.update_date "lastUpdate", P.updated_by "prevUpdater", P.update_date "prevUpdate"
  79. (
  80. select id, updated_by, update_date
  81. from theTable
  82. where (id, update_date) in (
  83. select id, max(update_date) as "max_update_date"
  84. from theTable
  85. )
  86. ) L
  87. (
  88. select T.id, T.updated_by, T.update_date
  89. from theTable T
  90. join (
  91. select secondUpdate.id, max(secondUpdate.update_date) max_previous_date
  92. from theTable secondUpdate
  93. join (
  94. select id, max(update_date) as "max_update_date"
  95. from theTable
  96. ) lastUpdate
  97. on secondUpdate.id = lastUpdate.id
  98. and secondUpdate.update_date < lastUpdate.max_update_date
  99. group by secondUpdate.id
  100. ) lastPreviousUpdate
  101. on T.id = lastPreviousUpdate.id
  102. and T.update_date = lastPreviousUpdate.max_previous_date
  103. ) P
  104. on L.id = P.id
  105. ;

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.