SQLite-根据修改日期合并2个表,必要时插入新行

时间:2019-05-01 09:47:27

标签: sqlite

我有一个带有ID列的表,该列是主键,并且也是唯一的。此外,该表具有修改的日期列。

我在2个数据库中有相同的表,并且我希望将两者合并到一个数据库中。表中的合并方案如下:

  • 如果没有ID,则插入记录;
  • 如果ID存在,则仅当修改日期大于现有行的日期时才进行更新。

例如,具有:

表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中完成此任务?

我在Node.js上使用sqlite3

2 个答案:

答案 0 :(得分:0)

首先创建表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,并使用EXISTS仅获取所需的行,这是一种非常有效的检查所需条件的方法。
我有>=而不是{{1}的>子句中的WHERE,以防两个表中的行具有相同的Table1和相同的{{1 }}值。
在这种情况下,将插入id中的行。

如果要合并modifiedat中的2个表,可以使用REPLACE

Table2

答案 1 :(得分:0)

在Sqlite 3.24中添加的UPSERT表示法很容易:

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;