table1.id and table2.id are both
primary keys. table2.old_id is also
unique.
It follows that table1.id will still
be unique after this update.
That ain't necessarily so.
It seems old_ID and (new) ID are of the same data type. A row in table1 that has no matching row in table2 based on the predicate (table1.ID = table2.old_ID
) would not be updated. A different row could match a (new) ID value, hence get updated, with the same value as that row that didn't get updated.
Here's an example using Standard SQL (works in SQL Server 2008, not it Access/Jet) which I hope you can follow. Note I've re-written your INNER JOIN
using an EXISTS
construct to fit the logic of what I am trying to convey:
WITH Table1 (ID) AS
(
SELECT ID
FROM (
VALUES (1),
(2),
(3),
(4)
) AS Table2 (ID)
),
Table2 (old_ID, ID) AS
(
SELECT old_ID, ID
FROM (
VALUES (1, 55),
(2, 99),
(3, 4)
) AS Table2 (old_ID, ID)
)
-- ID of rows that will not be updated:
SELECT T1.ID
FROM Table1 AS T1
WHERE NOT EXISTS (
SELECT *
FROM Table2 AS T2
WHERE T1.ID = T2.old_ID
)
UNION ALL
-- updated IDs
SELECT T2.ID
FROM Table2 AS T2
WHERE EXISTS (
SELECT *
FROM Table1 AS T1
WHERE T1.ID = T2.old_ID
);
The resultset:
ID
---
4 --<-- duplicate
55
99
4 --<-- duplicate
In other words, even though all the following are unique:
(table1.ID)
(table2.ID)
(table2.old_ID)
...the following may contain duplicates:
table1.ID
UNION ALL
table2.ID