我有一个表,我想根据上一行中的值更新表中的值。在这里,我想将“值”更新为上一行“值+调整”的总和。我想在SQLite中做到这一点。
原始表
Name | Value | Adjustment
Apple | 10 | 5
Ball | 20 | 10
Cat | 30 | 15
Dog | 40 | 0
Emily | 50 | 10
Frog | 60 | 0
Goat | 70 | 5
更新表
Name | Value | Adjustment
Apple | 10 | 5
Ball | 15 (10+5) | 10
Cat | 25 (15+10) | 15
Dog | 40 (25+15) | 0
Emily | 40 (40+0) | 10
Frog | 50 (40+10) | 0
Goat | 50 (50+0) | 5
我可以使用python做到这一点,但我想知道在SQLite中是否有快速有效的方法。
答案 0 :(得分:1)
如果您使用的是最新版本的sqlite(3.25或更高版本),则使用窗口功能非常容易。以下假设您正在按名称列进行排序,如示例输入和输出中所示:
CREATE TABLE example(name TEXT, value INTEGER, adj INTEGER);
INSERT INTO example VALUES('Apple',10,5);
INSERT INTO example VALUES('Ball',20,10);
INSERT INTO example VALUES('Cat',30,15);
INSERT INTO example VALUES('Dog',40,0);
INSERT INTO example VALUES('Emily',50,10);
INSERT INTO example VALUES('Frog',60,0);
INSERT INTO example VALUES('Goat',70,5);
CREATE INDEX example_idx_name ON example(name); -- Used in the window ordering
SELECT name AS "Name"
, first_value(value) OVER names + sum(adj) OVER names - adj AS "Value"
, adj AS "Adjustment"
FROM example
WINDOW names AS (ORDER BY name)
ORDER BY name;
产生:
Name Value Adjustment
---------- ---------- ----------
Apple 10 5
Ball 15 10
Cat 25 15
Dog 40 0
Emily 40 10
Frog 50 0
Goat 50 5
现在,要改为更新表... UPDATE
的问题在于行以任意顺序更新(可能是按rowid进行的,但您不应该依赖这样的实现细节),因此可以确实不是基于“上一个”行来做某事。一种方法:使用上述查询的版本来填充临时表,然后使用该表来更新原始表:
CREATE TEMP TABLE staging(id INTEGER PRIMARY KEY, value INTEGER);
INSERT INTO staging
SELECT rowid, first_value(value) OVER names + sum(adj) OVER names - adj
FROM example WINDOW names AS (ORDER BY name);
UPDATE example AS e SET value = (SELECT value FROM staging AS s WHERE s.id = e.rowid);
DROP TABLE staging;
SELECT * FROM example ORDER BY name;
name value adj
---------- ---------- ----------
Apple 10 5
Ball 15 10
Cat 25 15
Dog 40 0
Emily 40 10
Frog 50 0
Goat 50 5
答案 1 :(得分:0)
一种选择是通过.read_sql()
将其加载到pandas
DataFrame中,计算下一个Value
单元格值,然后通过.to_sql()
转储到SQLite中。行:
import sqlite3
import pandas as pd
conn = sqlite3.connect(...)
df = pd.read_sql_table(name_of_table, conn)
for i in range(1, len(df)):
df.iloc[i, 1] = df.iloc[i - 1, 1] + df.iloc[i - 1, 2]
df.to_sql(name=name_of_table, con=conn, if_exists='replace', index=False)
请注意"replace"
if_exists
的行为-它将在插入新行之前删除表。