使用WHERE条件将行插入表中,并从SQLite中的另一个表中加入JOIN

时间:2019-05-29 14:52:26

标签: sqlite

我有两个表(例如表1和表2),每个表中都有8列(v_id,p_id,cat,s1,s2,s3,s4,s5,s6,u_name,P_date)

我想在以下情况下将值从table2插入table1中:

  1. 如果表1中已经存在v_id,并且表2中的p_id与表1相匹配,则应将表1中的v_id替换为表2中的v_id。
  2. 如果表1中不存在v_id,则应将这些v_id添加到表1中
  3. 如果v_id存在,但表2中的p_id与表1不匹配,则应在表1中添加v_id。

到目前为止,我尝试过:

我已经启动了这样的表:

CREATE TABLE IF NOT EXISTS table1(v_id, cat TEXT, s1 TEXT,s2 TEXT,s3 TEXT, s4 TEXT,s5 TEXT,s6 TEXT, u_name TEXT, p_date DATE, p_id TEXT)

CREATE TABLE IF NOT EXISTS table2(v_id, cat TEXT, s1 TEXT,s2 TEXT,s3 TEXT, s4 TEXT,s5 TEXT,s6 TEXT, u_name TEXT, p_date DATE, p_id TEXT)

我已经在表1和表2中插入了一些数据,并尝试了以下代码:

INSERT OR REPLACE INTO table1 SELECT * FROM table2
LEFT JOIN table1 ON table2.v_id=table1.v_id
WHERE table2.p_id=table1.p_id OR table1.v_id IS NULL

但是,它给了我以下错误:

"table table1 has 11 columns but 22 values were supplied"

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

SELECT *返回22列。为什么?因为它从JOIN返回列,所以不仅返回table2中的列。来自sqlite SELECT doc

  

如果加入操作员是“ LEFT JOIN”或“ LEFT OUTER JOIN”,则在   如果应用了ON或USING过滤子句,则额外一行   添加到原始左侧输入中每一行的输出中   组合数据集中根本没有行的数据集   (如果有)。添加的行的列中包含NULL值,   通常包含从右侧输入数据集中复制的值。

SELECT table2.* from .....将解决那个问题。

让我们暂时忘记INSERT并评估将返回哪些行

SELECT * FROM table2
LEFT JOIN table1 ON table2.v_id=table1.v_id
WHERE table2.p_id=table1.p_id OR table1.v_id IS NULL

它将不会选择table2.v_id = table1.v_id AND table2.p_id != table1.p_id所在的行,因此永远不会满足条件3。

除非table1具有UNIQUE或PRIMARY KEY约束,否则将永远不会有替换,因此将永远不会满足条件1(它将简单地插入table2中的行)。从sqlite ON CONFLICT文档中:

  

替换

     

发生违反UNIQUE或PRIMARY KEY约束的情况时,REPLACE算法将删除导致   在插入或更新当前行之前违反约束   并且该命令继续正常执行。如果非空约束   发生冲突时,REPLACE解决冲突将替换为NULL   值和该列的默认值,或者该列没有   默认值,则使用ABORT算法。如果检查约束   发生冲突时,始终使用REPLACE冲突解决算法   像ABORT一样。

您将需要在table1上创建索引才能使用REPLACE操作。在v_id,p_id上的复合索引也许可以解决问题。类似于CREATE UNIQUE INDEX "vid_pid_idx" on table1 (v_id,p_id)。然后只需INSERT OR REPLACE INTO table1 SELECT * FROM table2即可完成目标。

v_ids和p_ids相等的行将“ REPLACE”,因为UNIQUE约束将被“违反”。
将插入来自table2的所有其他行。