I have two history tables that track changes in database values, using a revision id to track the individual changes. e.g.
Table 1:
rev | A | B
=================
1 | 100 | 'A'
4 | 150 | 'A'
7 | 100 | 'Z'
Table 2:
rev | C | D
==================
1 | 200 | True
5 | 0 | True
8 | 0 | False
The goal would be to merge the two tables into:
rev | A | B | C | D
===============================
1 | 100 | 'A' | 200 | True
4 | 150 | 'A' | 200 | True
5 | 150 | 'A' | 0 | True
7 | 100 | 'Z' | 0 | True
8 | 100 | 'Z' | 0 | False
The idea being that for for a given revision, I would take the values corresponding to that revision or the highest revision less than it.
The SQL query that comes to mind would be something akin to cross joining the two tables with constraint rev1 < rev2, then selecting rows using a subquery where rev1 = max(rev1) for each given rev2; unioning this query with its counterpart exchanging rev2 and rev1; and finally filtering out duplicates from where rev1 = rev2.
The questions are:
To join two tables based on a column match without loosing any of the data from the left table, you would use a LEFT OUTER JOIN. Left outer joins are used when you want to get all the values from one table but only the records that match the left table from the right table.
Sometimes you might want to list the records from one table or query with those from one or more other tables to form one set of records - a list with all the records from the two or more tables. This is the purpose of a union query in Access.
SQL Fiddle
select
coalesce(t1.rev, t2.rev) rev,
coalesce(a, lag(a, 1) over(order by coalesce(t2.rev, t1.rev))) a,
coalesce(b, lag(b, 1) over(order by coalesce(t2.rev, t1.rev))) b,
coalesce(c, lag(c, 1) over(order by coalesce(t1.rev, t2.rev))) c,
coalesce(d, lag(d, 1) over(order by coalesce(t1.rev, t2.rev))) d
from
t1
full join
t2 on t1.rev = t2.rev
order by rev
This can be achieved by sub queries
SELECT ISNULL(Table1.rev,Table2.rev) AS rev
,ISNULL(A,(SELECT TOP 1 A FROM Table1 AS T1 WHERE ISNULL(Table1.rev,Table2.rev) > T1.rev AND A IS NOT NULL ORDER BY rev DESC)) AS A
,ISNULL(B,(SELECT TOP 1 B FROM Table1 AS T1 WHERE ISNULL(Table1.rev,Table2.rev) > T1.rev AND B IS NOT NULL ORDER BY rev DESC)) AS B
,ISNULL(C,(SELECT TOP 1 C FROM Table2 AS T2 WHERE ISNULL(Table1.rev,Table2.rev) > T2.rev AND C IS NOT NULL ORDER BY rev DESC)) AS C
,ISNULL(D,(SELECT TOP 1 D FROM Table2 AS T2 WHERE ISNULL(Table1.rev,Table2.rev) > T2.rev AND D IS NOT NULL ORDER BY rev DESC)) AS D
FROM Table1
FULL OUTER JOIN Table2
ON Table1.rev = Table2.rev
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With