首页 > 解决方案 > 当有多个同名时更新sqlite数据库中的值

问题描述

我会尽力解释我的问题。

我正在研究cs50,C$50 Finanace目前正在实现一个名为sell 的函数。此功能的目的是将特定用户的现金价值更新到数据库中并更新他的投资组合。

我正在努力更新投资组合数据库。

这是为了更好地澄清数据库查询:

CREATE TABLE 投资组合(id INTEGER,用户名 TEXT NOT NULL,符号 TEXT NOT NULL,共享 INTEGER,PRIMARY KEY(id));

假设我有这些值:

编号 | 用户名 | 符号 | 分享

1 | 阿姆 | 苹果 | 20

2 | 阿姆 | NFLX | 5

3 | 阿姆 | 苹果 | 5

用户出售他的一些股票。我必须更新shares. 如果是NFLX符号,那很容易。像下面这样的简单查询就足够了

db.execute("更新投资组合 SET share=shares - ? WHERE username=? AND symbol=?", int(shares), username, quote["symbol"])

但是,如果我想要更新AAPL共享,这就是问题出现的地方。如果我执行上面的查询,假设用户卖出了 5 股,上面的查询会将AAPLid1和20 中的股份都更改3为 20,使总股份AAPL变为 40 而不是 20。

我应该考虑哪种方法?在将它们插入portfolio表格之前,我应该根据符号对股票进行分组吗?如果是这样,怎么做?或者有没有可以解决我的问题的查询?

标签: pythonsqlitecs50

解决方案


如果您的 SQLite 版本是 3.33.0+,则使用如下UPDATE...FROM语法:

UPDATE portfolio AS p
SET shares = (p.id = t.id) * t.shares_left
FROM (
  SELECT MIN(id) id, username, symbol, shares_left 
  FROM (
    SELECT *, SUM(shares) OVER (ORDER BY id) - ? shares_left -- change ? to the number of stocks the user sold 
    FROM portfolio
    WHERE username = ? AND symbol = ?
  ) 
  WHERE shares_left >= 0
) AS t
WHERE p.username = t.username AND p.symbol = t.symbol AND p.id <= t.id;

窗口函数SUM()返回份额的增量总和,直到达到已售出的份额数。
UPDATE语句将在所有id小于第一个id超过已售股票的行中,将与等于第一个的行中超过已售股票的列shares设置为增量总和与已售数量之间的差值分享。0idid

查看简化的演示

对于以前的版本,您可以使用:

WITH 
  cte AS (
    SELECT MIN(id) id, username, symbol, shares_left 
    FROM (
      SELECT *, SUM(shares) OVER (ORDER BY id) - ? shares_left -- change ? to the number of stocks the user sold  
      FROM portfolio
      WHERE username = ? AND symbol = ?
    ) 
    WHERE shares_left >= 0
  )
UPDATE portfolio
SET shares = (id = (SELECT id FROM cte)) * (SELECT shares_left FROM cte) 
WHERE (username, symbol) = (SELECT username, symbol FROM cte) AND id <= (SELECT id FROM cte)

查看简化的演示


推荐阅读