[英]Insert previous value of field using INSERT INTO and subquery SELECT
I have the following schema:我有以下架构:
CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, val INTEGER, previousval INTEGER)
I want to store the value val
and automatically copy the previous value into the column previousval
:我想存储值
val
并自动将先前的值复制到列previousval
中:
id val previousval
1 100 NULL
2 200 100
3 300 200
I tried the following query and SQLite gives me an error message I don't understand.我尝试了以下查询,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
I tried another query:我尝试了另一个查询:
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))
The result is not what I expect and I don't understand why.结果不是我所期望的,我不明白为什么。
id val previousval
1 100 NULL
2 200 NULL
3 300 NULL
I use sqlite-amalgamation-3310100.我使用 sqlite-amalgamation-3310100。 I also use SQLiteStudio for testing.
我也使用 SQLiteStudio 进行测试。
How to automatically copy the value of a field into a column using INSERT INTO
?如何使用
INSERT INTO
自动将字段的值复制到列中?
The problem with your attempt is that you are trying to correlated the subquery with a value that is not yet inserted.您尝试的问题是您试图将子查询与尚未插入的值相关联。 That can't work.
那是行不通的。
You could just do:你可以这样做:
insert into test as test1 (id, val, previousval)
values(
null,
1,
(select val from test order by id desc limit 1)
)
Note: if id
is an auto-incremented key (as it looks like), then just skip that column when inserting:注意:如果
id
是一个自动递增的键(看起来像),那么在插入时跳过该列:
insert into test as test1 (val, previousval)
values(
1,
(select val from test order by id desc limit 1)
)
Bottom line, I would not actually recommend storing that derived information in the table itself: for example, if val
is updated, then you need some additional processing to reset the following record.最重要的是,我实际上不建议将派生信息存储在表本身中:例如,如果更新了
val
,那么您需要一些额外的处理来重置以下记录。
You can easily compute that information on the fly when needed, or put in a view.您可以在需要时轻松地即时计算该信息,或放入视图中。 If your version of SQLite supports window functions:
如果您的 SQLite 版本支持 window 功能:
select id, val, lag(val) over(order by id) previousval from mytable
In earlier versions:在早期版本中:
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
In your CREATE
statement of the table you define the column id
as:在表的
CREATE
语句中,您将列id
定义为:
id INTEGER PRIMARY KEY
and this means that it will be unique and auto incremented.这意味着它将是唯一的并且会自动递增。
But this does not mean that it will always increase.但这并不意味着它会一直增加。
If you delete a row, the next time that you will insert a new row the missing id value may be reused, so the logic that you want to apply will not work.如果删除一行,下次插入新行时可能会重复使用丢失的 id 值,因此您要应用的逻辑将不起作用。
So as it is explained here , you must disable the reuse of ids and this can be done by using the keyword AUTOINCREMENT
in the definition of the column:因此,正如这里所解释的,您必须禁用 id 的重用,这可以通过在列的定义中使用关键字
AUTOINCREMENT
来完成:
CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, ...)
Then you can insert new rows like this:然后你可以像这样插入新行:
INSERT INTO test(val, previousval) VALUES
(100, (SELECT val FROM test ORDER BY id DESC LIMIT 1));
INSERT INTO test(val, previousval) VALUES
(200, (SELECT val FROM test ORDER BY id DESC LIMIT 1));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.