SQLite高效运行总计

时间:2015-05-07 00:18:51

标签: sqlite

我在SQLite中有一个交易表

编号日期类别金额runningBalance

我希望运行余额列在表按第一个日期和第二个排序之后有一个金额列的运行总和。

我可以在阅读时使用选择。但是这张桌子有可能变得非常大,我不想每次都重新计算。我想创建一个触发器,其中插入/编辑的事务之后的所有事务(按日期然后编号)更新其runningBalance值。

这意味着计算会减少......因为最近的交易很可能会被更频繁地编辑,而较旧的交易很少。它还会将计算扩展到写入,以便读取接近即时。

任何人都可以提供有关如何设置此类触发器的帮助吗?

到目前为止,这是我所拥有的,但它没有给出预期的结果。并且每次都重新计算。不只是改变后的那些。

CREATE TRIGGER RunningTotal AFTER UPDATE ON Transactions FOR EACH ROW
BEGIN
    UPDATE Transactions 
       SET RunningBalance = (
        SELECT (
                   SELECT sum(Amount) 
                     FROM TopInfo t2
                    WHERE t2.Date <= t1.Date
               )
          FROM Transactions t1
    );
END;

谢谢!

1 个答案:

答案 0 :(得分:0)

我设法找到一种有效的方法。不知道它有多高效。很高兴听到有人知道更新Balance列的更有效方法。

CREATE TRIGGER Balance AFTER UPDATE OF Amount ON Transactions FOR EACH ROW
BEGIN
    UPDATE Transactions
       SET Balance = (
        SELECT Balance
          FROM (
                   SELECT TransactionID,
                          (
                              SELECT sum(t2.Amount) 
                                FROM Transactions t2
                               WHERE t2.Date <= t1.Date
                               ORDER BY Date
                          )
                          AS Balance
                     FROM Transactions t1
                    WHERE TransactionID = Transactions.TransactionID
                    ORDER BY Date
               )
    )
     WHERE Transactions.Date >= NEW.Date;
END;

更新:

CREATE TRIGGER Balance AFTER UPDATE OF Amount ON Transactions FOR EACH ROW
BEGIN
    UPDATE Transactions
       SET Balance = (
        SELECT Balance
          FROM (
                   SELECT TransactionID,
                          (
                              SELECT sum(t2.Amount) 
                                FROM Transactions t2
                               WHERE CASE WHEN t2.Date = t1.Date THEN t2.TransactionID <= t1.TransactionID ELSE t2.Date <= t1.Date END
                               ORDER BY Date,
                                        TransactionID
                          )
                          AS Balance
                     FROM Transactions t1
                    WHERE TransactionID = Transactions.TransactionID
                    ORDER BY Date,
                             TransactionID
               )
    )
     WHERE Transactions.Date >= NEW.Date;
END;

我已经完成了更多的总计,并提出了两种方法。第二个比第一个慢得多。任何想法为什么???

方法1

SELECT TransactionID,Date, Account, Amount,
(SELECT sum(t2.Amount)
FROM Transactions t2
WHERE
CASE WHEN t2.Date = t1.Date
THEN t2.TransactionID <= t1.TransactionID
AND t2.Account == t1.Account
ELSE t2.Date <= t1.Date
AND t2.Account == t1.Account
END
ORDER BY Date, TransactionID)
AS Balance
FROM Transactions t1
    ORDER BY Date, TransactionID

方法2

SELECT n.TransactionID, n.Date, n.Account, n.Amount,
SUM(o.Amount) As running_total
FROM Transactions n LEFT JOIN Transactions o
ON (
CASE WHEN o.Date = n.Date
THEN n.TransactionID >= o.TransactionID
AND o.Account == n.Account
ELSE n.Date >= o.Date
AND o.Account == n.Account
END
)
GROUP BY n.Account, n.Date, n.TransactionID
ORDER BY n.Date, n.TransactionID;