【问题标题】:Adding value of COUNT to an already existing value将 COUNT 的值添加到已经存在的值
【发布时间】:2020-12-27 10:08:55
【问题描述】:

我有一张用于管理库存移动的表格和一张用于管理库存的表格。 我想将物品在给定日期之间存在的移动计数添加到库存表中。

我的更新语句如下所示:

UPDATE inventory 
SET    quantity = quantity + 1
WHERE  ItemID IN 
       ( SELECT ItemID FROM movements
         WHERE  group = '3' AND store = '500'
         AND    DateMove BETWEEN 20201219 AND 20201223 )
AND    StoreNumber = '500'

如何更改此查询以将 ItemID 在移动中出现的次数添加到库存表中的数量?

我一直在想我可以添加一个 count(itemID) 和 group by 并在子查询中添加一个别名并在 + 之后使用别名,但它似乎不起作用。

感谢您的帮助

【问题讨论】:

  • 两个表的样本数据以及预期的输出将极大地帮助您解决问题。
  • 您所说的“项目在给定日期之间存在的移动计数”是什么意思?您的意思是“两个日期之间给定项目的移动计数”?

标签: sql oracle


【解决方案1】:

使用UPDATE,您可以使用相关子查询:

UPDATE inventory i
    SET quantity = (i.quantity +
                    (SELECT COUNT(*)
                     FROM movements m
                     WHERE m.ItemId = i.ItemId AND
                           m.group = 3 AND m.store = i.store AND
                           m.DateMove BETWEEN 20201219 AND 20201223 
                    )
                   )
WHERE i.store = 500 AND
      EXISTS (SELECT 1
              FROM movements m
              WHERE m.ItemId = i.ItemId AND
                    m.group = 3 AND m.store = 500 AND
                    m.DateMove BETWEEN 20201219 AND 20201223 
             );

请注意,我删除了 5003 周围的单引号。这些值看起来像数字。仅当它们是字符串时才使用单引号。

Oracle 还允许您在某些情况下使用子查询进行更新,因此这应该也可以:

update (select i.*,
               (SELECT COUNT(*)
                FROM movements m
                WHERE m.ItemId = i.ItemId AND
                      m.group = 3 AND m.store = i.store AND
                      m.DateMove BETWEEN 20201219 AND 20201223 
               ) as inc_quantity
       from inventory i
       where store = 500
      )
    set quantity = quantity + inc_quantity
    where quantity > 0;

【讨论】:

  • 嘿,第二个对我来说就像一个魅力。请您解释一下 table.* 的含义吗?我写的时候并不知道这意味着什么。
  • @AvivKaplan 。 . .这将从表中选择所有列。
【解决方案2】:

您似乎想要MERGE 声明和COUNT 动作:

MERGE INTO inventory dst
USING (
  SELECT ItemID,
         store,
         COUNT(*) AS num_movements
  FROM   movements
  WHERE  group = 3
  AND    store = 500
  AND    DateMove BETWEEN DATE '2020-12-19' AND DATE '2020-12-23'
  GROUP BY
         ItemId,
         store
) src
ON ( src.ItemId = dst.ItemId AND dst.StoreNumber = src.store )
WHEN MATCHED THEN
  UPDATE
  SET quantity = dst.quantity + src.num_movements;

(另外,如果值是数字,则使用数字文字而不是字符串文字,对于日期,使用日期文字而不是数字。)

【讨论】:

  • 直到我添加了 WHEN MATCHED THEN 和 WHEN NOT MATCHED THEN 之前它没有工作有没有办法让它只使用 UPDATE 工作?
【解决方案3】:

您需要一个相关的子查询。为简洁起见,我省略了所有其他 where 条件。

UPDATE inventory AS inv
SET quantity = quantity + (SELECT COUNT(*) FROM movements AS mov WHERE mov.itemID = inv.itemID);

【讨论】:

    【解决方案4】:

    我认为最好创建一个视图,例如

    CREATE OR REPLACE VIEW v_inventory AS
    SELECT i.*,
           SUM(CASE
               WHEN i.StoreNumber = 500 AND m."group" = 3 AND m.store = 500 AND
                    m.DateMove BETWEEN date'2020-12-19' AND date'2020-12-23' 
               THEN
                    1
               ELSE
                    0
                END) OVER (PARTITION BY m.ItemID) AS mov_quantity
      FROM inventory i
      LEFT JOIN movements m
        ON m.ItemID = i.ItemID
    

    而不是为了良好的数据库设计而应用 DML,因为已经可以计算出所需的计数,并且可能会产生以后的混淆

    【讨论】:

      猜你喜欢
      • 2014-01-13
      • 2011-03-04
      • 2017-12-23
      • 2020-12-08
      • 2023-03-03
      • 2022-01-22
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多