【问题标题】:Wrong math in sqlite3sqlite3中的数学错误
【发布时间】:2022-01-25 13:31:27
【问题描述】:

所以我正在为我的应用程序使用 sqlite3 数据库,简单数学计算的结果是错误的,因此我很担心.. 所以在这里,我必须找到进出库存的净流量,它们的流量是分别记录在两个单独的表中购买和库存流出..我将查询中的购买和使用(流出)材料按其产品ID分组,并从两个表中添加它们的数量,然后从两个表中减去添加的数量以获得该产品的剩余数量或该产品的净流量,但 sqlite3 数据库甚至无法进行简单的数学运算,

例如 - 当一个产品分别以 8 和 4 两个不同数量购买时,答案必须是 12,但它给出 24,而当同一产品以不同数量(如 7 和 4)被使用两次时,答案必须是 11,但它给出 22..

下面是我写的分别查找每个产品的netflow的SQL查询,

                  SELECT p.product_id,
                         SUM(p.quantity) AS total_inflow,
                         SUM(s.quantity) AS total_outflow,
                         SUM(p.quantity) - SUM(s.quantity) AS quantity_left,
                         s.UOM

                  FROM purchases p
                  INNER JOIN stock_out s ON p.product_id = s.product_id

                  GROUP BY p.product_id, s.product_id

【问题讨论】:

  • 请以CREATE TABLE语句的形式添加一个测试用例,再加上几条INSERT语句。然后根据特定数据提供该测试的实际结果以及您的预期结果。
  • 注意:您的 GROUP BY 只需要 p.product_ids.product_id,而不是两者,并且您的 SELECT 列表包含 s.UOM,这可能在功能上不依赖于 GROUP BY 术语。这可能是误解的根源。此外,由于JOINSUM(p.quantity) 可能不会产生您期望的结果。这取决于关系的类型(1-1 或 1-N)。
  • 如果同一产品有 1 行 in_flow 和 2 行 out_flow,则 SUM 会看到两次 in_flow 数量,并产生两倍的预期值。 out_flow 的数量总和也是如此。这都是由于 JOIN 行为。您的测试用例将显示您拥有哪种情况。但是你的逻辑容易受到这两个问题的影响。
  • 所以我从您的评论中得到的是,问题可能是由于 join 语句而发生的,那么我应该如何在没有 join 语句的情况下编写查询,这样问题就不会发生并且需要任务也完成了..对此有什么意见吗??
  • 请参阅下面的 2 个答案。一旦纠正了任何拼写错误,这两种方法都可以工作。

标签: database sqlite math


【解决方案1】:

当您有超过一行的 in_flow 或 out_flow 或两者时,另一个数量的 SUM 会因 JOIN 操作而受到影响。

要解决JOIN 问题,您可以执行以下操作,例如。为了解决 in_flow 和 no out_flow 的情况,并且我们也希望显示这些结果,我们可以为此使用外连接(已进行调整)。

如果有可能出现 out_flow 而没有相应的 in_flow,我们可以使用 FULL OUTER JOIN。我怀疑在这种情况下可能没有必要。

WITH in_flow AS (
        SELECT product_id, SUM(quantity) AS total_inflow
          FROM purchases
         GROUP BY product_id
     )
   , out_flow AS (
        SELECT product_id, SUM(quantity) AS total_outflow
          FROM stock_out
         GROUP BY product_id
     )
SELECT in_flow.product_id
     , total_inflow, COALESCE(total_outflow, 0) AS total_outflow
     , total_inflow - COALESCE(total_outflow, 0) AS remaining
  FROM      in_flow
  LEFT JOIN out_flow
    ON in_flow.product_id = out_flow.product_id
;

【讨论】:

  • 这样您将过滤掉仅在 2 个表中的一个中有一行的任何产品。
  • @forpas 没错。这个假设总是有任何 out_flow 的 in_flow。你不能发送你从未有过的东西......而且发帖人不想要没有 out_flow 的产品的结果。但是,与往常一样,这将取决于完整的要求。
【解决方案2】:

在 2 个表中分别汇总并使用 UNION ALL 作为结果。
然后再次聚合:

SELECT product_id, 
       SUM(total_inflow) AS total_inflow, 
       SUM(total_outflow) AS total_outflow,
       SUM(total_inflow) - SUM(total_outflow) AS quantity_left
FROM (
  SELECT product_id, SUM(quantity) AS total_inflow, 0 AS total_outflow
  FROM purchases 
  GROUP BY product_id 
  UNION ALL
  SELECT product_id, 0, SUM(quantity) 
  FROM stock_out 
  GROUP BY product_id
) 
GROUP BY product_id;

【讨论】:

  • 别忘了添加UNION ALL操作。
  • @JonArmstrong 我以为我做到了,但没有......谢谢
猜你喜欢
  • 2022-01-23
  • 1970-01-01
  • 2015-05-02
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多