I'm altering a table with a crap ton of data, which is going to take weeks to run. In the meantime, I'm creating a new table to write to while the original table is locked.
CREATE TABLE NEW_TABLE LIKE (OLD_TABLE INCLUDING ALL);
If I do this, I need to update my queries to read from both tables. So I'm creating a view combining both tables, which I'll use to query for the next month.
CREATE VIEW TABLE_VIEW AS
SELECT * FROM NEW_TABLE
UNION ALL
SELECT * FROM OLD_TABLE
On updates, I'll have to copy rows from OLD_TABLE
into NEW_TABLE
with certain fields changed. For example:
Old query:
UPDATE OLD_TABLE SET isPerson=false WHERE id=123 AND name=john
New query:
INSERT INTO NEW_TABLE (id, name, color, team, isPerson)
SELECT id, name, color, team, false
FROM OLD_TABLE
WHERE id = 123
AND name = john
ON DUPLICATE KEY UPDATE isPerson = false
This means there will be duplicate data (based on my primary keys) across the tables, in which case the corresponding rows in OLD_TABLE
would be outdated. How do I create the view to only include the rows from NEW_TABLE
when the same primary keys exist in both tables?
(Assume primary keys are id and name, and no other constraints on the table)
IDK why somebody minused OP question.
Consider scenario:
That's an absolutely valid use-case.
What OP needs is to use NOT EXISTS
predicate:
CREATE VIEW TABLE_VIEW AS
SELECT * FROM NEW_TABLE
UNION ALL
SELECT * FROM OLD_TABLE OT
WHERE NOT EXISTS(
SELECT 1 FROM NEW_TABLE NT
WHERE
NT.id = OT.id
AND NT.name = OT.name
)
Look: https://www.db-fiddle.com/f/xcEWWkaGputdHYnYqmwQhx/2
Note that by SQL Standard order is not guaranteed without ORDER BY
.
On most RDBMSs UNION ALL returns rows from top to bottom.
But don't forget that by SQL Standard order of rows is not guaranteed without ORDER BY
It could work now but it could be broken after even a minor patch.
So to make such view absolutely correct some changes to tables are needed.
Eg add a new field insert_date
into tables or even:
CREATE VIEW TABLE_VIEW AS
SELECT * FROM (
SELECT *, 0 as display_order FROM NEW_TABLE
UNION ALL
SELECT *, 1 as display_order FROM OLD_TABLE OT
WHERE NOT EXISTS(
SELECT 1 FROM NEW_TABLE NT
WHERE
NT.id = OT.id
AND NT.name = OT.name
)
)
ORDER BY display_order
https://www.db-fiddle.com/f/xcEWWkaGputdHYnYqmwQhx/3
Just using UNION
could gives the same results
But:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.