SQLite - объединить 2 таблицы в соответствии с датой изменения, при необходимости вставить новую строку - PullRequest
1 голос
/ 01 мая 2019

У меня есть таблица с идентификатором столбца, этот столбец является первичным ключом и уникальным Кроме того, в таблице есть измененный столбец даты.

У меня одна и та же таблица в 2 базах данных, и я хочу объединить обе в одну базу данных. Сценарий объединения в таблице выглядит следующим образом:

  • Вставить запись, если идентификационный номер отсутствует;
  • Если идентификатор существует, обновлять только в том случае, если дата изменения превышает дату существующей строки.

Например, имеющий:

Таблица 1:

id | name | createdAt  | modifiedAt
---|------|------------|-----------
1  | john | 2019-01-01 | 2019-05-01
2  | jane | 2019-01-01 | 2019-04-03

Таблица 2:

id | name | createdAt  | modifiedAt
---|------|------------|-----------
1  | john | 2019-01-01 | 2019-04-30
2  | JANE | 2019-01-01 | 2019-04-04
3  | doe  | 2019-01-01 | 2019-05-01

Итоговая таблица будет:

id | name | createdAt  | modifiedAt
---|------|------------|-----------
1  | john | 2019-01-01 | 2019-05-01
2  | JANE | 2019-01-01 | 2019-04-04
3  | doe  | 2019-01-01 | 2019-05-01

Я читал о INSERT OR REPLACE, но я не мог понять, как можно применить условие даты. Я также знаю, что могу просмотреть каждую пару одинаковых строк и проверить дату вручную, но это потребует много времени и производительности. Следовательно, существует ли эффективный способ сделать это в SQLite?

Я использую sqlite3 на Node.js.

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Запись UPSERT , добавленная в Sqlite 3.24, упрощает:

INSERT INTO table1(id, name, createdAt, modifiedAt)
  SELECT id, name, createdAt, modifiedAt FROM table2 WHERE true
  ON CONFLICT(id) DO UPDATE
  SET (name, createdAt, modifiedAt) = (excluded.name, excluded.createdAt, excluded.modifiedAt)
  WHERE excluded.modifiedAt > modifiedAt;
0 голосов
/ 01 мая 2019

Сначала создайте таблицу Table3:

CREATE TABLE Table3 (
    id  INTEGER,
    name    TEXT,
    createdat   TEXT,
    modifiedat  TEXT,
    PRIMARY KEY(id)
);

, а затем вставьте строки следующим образом:

insert into table3 (id, name, createdat, modifiedat)
select id, name, createdat, modifiedat from (
  select * from table1 t1
  where not exists (
    select 1 from table2 t2
    where t2.id = t1.id and t2.modifiedat >= t1.modifiedat
  )  
  union all 
  select * from table2 t2 
    where not exists (
    select 1 from table1 t1
    where t1.id = t2.id and t1.modifiedat > t2.modifiedat
  )  
)

Используется UNION ALL для 2 таблиц и получается только необходимые строки с EXISTS, что является очень эффективным способом проверки желаемого условия.
У меня >= вместо > в предложении WHERE для Table1 в случае, если в 2 таблицах есть строка с одинаковыми id и одинаковыми modifiedat значениями.
В этом случае будет вставлена ​​строка из Table2.

Если вы хотите объединить 2 таблицы в Table1, вы можете использовать REPLACE:

replace into table1 (id, name, createdat, modifiedat)
select id, name, createdat, modifiedat 
from table2 t2
where 
  not exists (
    select 1 from table1 t1
    where (t1.id = t2.id and t1.modifiedat > t2.modifiedat)
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...