Sqlite使用sum插入或更新

时间:2014-07-17 14:19:59

标签: python sqlite

我有一个用于记录数据输入/输出的表:

CREATE TABLE io(iodate DATE, xt INTEGER, rv INTEGER)

它旨在按日期存储总传输数据。

要更新它,我使用了一堆查询(混合了伪代码和SQL):

SELECT * FROM io WHERE iodate=<today>
if no result:
   INSERT INTO io(iodate, xt, rv) VALUES (...)
else:
   UPDATE io SET rv+=<new_rv> xt+=<new_xt> WHERE iodate=<today>

我相信有更方便的方法来实现这一目标。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

假设iodate列上的主键您可以使用INSERT OR REPLACE,就像@Martijn_Pieters所说,但您可以通过2种方式执行此操作:

首先是查询当前数据,就像你一样,然后&#34;插入或替换&#34;:

SELECT * FROM io WHERE iodate = ?;
...
INSERT OR REPLACE INTO io VALUES (?, ?, ?);

要插入的参数应已包含xtrv的当前值和新值的总和。

第二是在一个查询中执行所有操作,但无论如何选择都已完成,只是它在子查询中:

INSERT OR REPLACE INTO io
                select iodate, xt + ?, rv + ? from (
                       SELECT iodate, xt, rv
                         FROM io
                        WHERE iodate = ?
                        union all
                       select ? as iodate, 0 as xt, 0 as rv
                ) limit 1;

第二个解决方案的主要缺点是您必须重复iodate两次,因此参数应按以下顺序传递:<new_xt>, <new_rv>, <iodate>, <iodate>,尽管它不会影响性能。

好处是它总是一个查询,无论该行是否已经在表中。

很难说哪一个更快。你必须自己测量它。

您还可以考虑使用SQLite的日期和时间功能,这样您就不必每次都通过iodate。我怀疑您的应用程序将始终传递iodate的当前数据,在这种情况下,您可以使用now()函数iodate或任何其他相关函数,因此它符合您的日期格式。请参阅有关可用日期和时间函数的SQLite文档。

答案 1 :(得分:0)

我担心Python sqlite3中没有你想要的快捷方式。您可以查看sqlite3 here的说明。

我建议你写这样的代码。 (与使用伪代码时一样。)

...
def findData():
    SELECT * FROM io WHERE iodate=<today>
def updateData():
    update operation
def insertData():
    insert operation
[updateData() if findData() else insertData()]
...

由于更新/查找/插入是处理数据库时最常用的操作,因此将它们打包到函数中将是一个很好的解决方案。