Let's say I have the following table with data:
sales:
| id | timestamp | product | price |
|---|---|---|---|
| 1 | 2014-01-01 01:02:03 | phone | 14.99 |
| 2 | 2014-01-01 03:02:03 | car | 1200.00 |
And then we have transactions stored in a separate table
cdc:
| type | id | timestamp | product | price |
|---|---|---|---|---|
| DELETE | 1 | 2014-01-01 04:02:03 | ||
| APPEND | 3 | 2014-01-02 04:02:03 | computer | 799.00 |
| UPDATE | 3 | 2014-01-02 04:02:03 | computer | 805.00 |
Would it be possible to do a single query to get the 'current table' up to a current timestamp? For example, something like:
-- only takes into account APPENDS
SELECT * FROM sales WHERE timestamp > '2014-02-01 00:00:00'
UNION
SELECT * FROM sales WHERE type='APPEND' AND timestamp > '2014-02-01 00:00:00'
But also including UPDATEs and DELETEs? I suppose a procedural table function is fine as well here.
For example, the table up to current is:
| id | timestamp | product | price |
|---|---|---|---|
| 2 | 2014-01-01 03:02:03 | car | 1200.00 |
| 3 | 2014-01-02 04:02:03 | computer | 805.00 |
(Any database dialect is fine here.)
This is T-SQL (The DDL and DML is bespoke, as is inclusion of the schema), but this should work in most dialects, or need minimal changes. First, I would use a CTE to
ROW_NUMBERby ID, to get the "latest" row to have a row number of 1. Then you could get the rows from the original table where no rowsEXISTSin the CTE, and thenUNION ALLto "Top 1 per group" row from the CTE:A note that the 2 entries for
id3have the same value fortimestampand there is nothing else toORDERthat data by. As such the row returned is arbitrary. Likely you should have an additional always ascending id column in that table, which you should add to theORDER BYclause forROW_NUMBERin descending order too (ORDER BY timestamp DESC, YourAscendingID DESC). This is why the above may return799.00for the value ofid3(as they both have the same value fortimestamp).You could likely assume that an
APPENDalways occurs before anUPDATE, that always occurs before aDELETE, and then use aCASEexpression, but if you have 2UPDATEs at the same time, then which you get would be completely arbitrary. TheCASEexpression would be the following, but as mentioned, is flawed with 2UPDATEs at the sametimestamp:Again, you would order the above in descending order.