I'm not sure how a temporal database like marc_s mentioned works, but if you're using SQL Server 2008 or later, you can take advantage of its built-in Change Data Capture (CDC) functionality:
Enabling CDC uses the replication transaction log to store the inserts, updates, and deletes for a table and creates table-valued functions which allow you to retrieve the rows as of a given date/time, or to retrieve just the changes.
You can't rely on CDC alone, though, because your transaction log will become unmanageably big and slow. So what you do is:
- enable CDC,
- create a history table using the same schema as the original table, but adding a couple more columns for storing row version information (much like a slowly-changing dimension in a relational OLAP database), and
- create a job which will periodically polls the CDC functions for changes since its last load and pushes them to the history table
Then you can then use the history table in your queries, joining to it as you normally would, but with an additional predicate(s) to get the record "as-of" whatever date you want.