我具有以下架构:
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
将字段的值自动复制到列中?
您可以做:
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
CREATE
语句中,将id
列定义为:id INTEGER PRIMARY KEY
这意味着它将是唯一的并自动递增。但这并不意味着它会一直增加。如果您删除一行,则下次您将插入新行时,missing id值可能会被重用,因此您要应用的逻辑将不起作用。因此,正如[C0]所述,您必须禁用ID的重用,这可以通过在列的定义中使用关键字here来完成:
AUTOINCREMENT
然后您可以像这样插入新行:
CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, ...)