使用INSERT INTO和子查询SELECT插入字段的先前值

问题描述 投票:0回答:2

我具有以下架构:

CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, val INTEGER, previousval INTEGER)

我要存储值val,并自动将以前的值复制到列previousval

id  val previousval
1   100 NULL
2   200 100
3   300 200

我尝试了以下查询,SQLite给了我我不明白的错误消息。

INSERT INTO test as test1 (id, val, previousval) VALUES (NULL, 1, (SELECT test2.val FROM test AS test2 WHERE test2.id<test1.id ORDER BY test2.id DESC LIMIT 1))
> no such column: test1.id

我尝试了另一个查询:

INSERT INTO test (id, val, previousval) VALUES (NULL, 100, (SELECT test2.val FROM test AS test2 WHERE test2.id<id ORDER BY test2.id DESC LIMIT 1)) 
INSERT INTO test (id, val, previousval) VALUES (NULL, 200, (SELECT test2.val FROM test AS test2 WHERE test2.id<id ORDER BY test2.id DESC LIMIT 1)) 
INSERT INTO test (id, val, previousval) VALUES (NULL, 300, (SELECT test2.val FROM test AS test2 WHERE test2.id<id ORDER BY test2.id DESC LIMIT 1)) 

结果不是我期望的,我不明白为什么。

id  val previousval
1   100 NULL
2   200 NULL
3   300 NULL

我使用sqlite-amalgamation-3310100。我也使用SQLiteStudio进行测试。

如何使用INSERT INTO将字段的值自动复制到列中?

sql sqlite sql-insert
2个回答
0
投票
尝试的问题是,您试图将子查询与尚未插入的值相关联。那行不通。

您可以做:

insert into test as test1 (id, val, previousval) values( null, 1, (select val from test order by id desc limit 1) )

注意:如果id是自动递增的键(看起来像),则在插入时跳过该列:

insert into test as test1 (val, previousval) values( 1, (select val from test order by id desc limit 1) )

底线,实际上我不建议将派生的信息存储在表本身中:例如,如果更新了val,则需要进行一些其他处理来重置以下记录。 

您可以根据需要随时轻松地计算这些信息,也可以将其放在视图中。如果您的SQLite版本支持窗口功能:

select id, val, lag(val) over(order by id) previousval from mytable

在早期版本中:

select t.id, t.val, (select val from mytable t1 where t1.id < t.id order by t1.id desc limit 1) previousval from mytable t


0
投票
在表的CREATE语句中,将id列定义为:

id INTEGER PRIMARY KEY

这意味着它将是唯一的并自动递增。但这并不意味着它会一直增加。如果您删除一行,则下次您将插入新行时,

missing id值可能会被重用,因此您要应用的逻辑将不起作用。因此,正如[C​​0]所述,您必须禁用ID的重用,这可以通过在列的定义中使用关键字here来完成:

AUTOINCREMENT
然后您可以像这样插入新行:

CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, ...)

© www.soinside.com 2019 - 2024. All rights reserved.