【问题标题】:SQL Merge Quantity of Variation (mother item)SQL 合并变量数量(母项)
【发布时间】:2021-02-01 13:33:18
【问题描述】:

我绝对不是 SQL 专业人士。所以请原谅一些错误的假设奇怪的代码等。 我目前正在尝试合并 ebay 市场的所有商品的数量。我已经设法更新了几乎所有项目。但是我确实对一些也位于我们数据库中的特定项目有点麻烦。每个变体项目都有一个(母项目)显示在我们的 ERP 系统中。 这些母项目确实有一个 Variation-ID (0)。其他变体确实具有特定颜色的variation.ids(例如黑色= 1,绿色= 2,等等)。 由于我们的 ERP 系统确实在某些掩码中设置了变化项目的最低数量(对于母项目)来执行触发(修改所有项目),为了防止超卖,我需要用与变异相关的最低数量。

以下陈述

EI.tecdocinfo = lbs.shop 何时匹配且 LBS.shop = '0'

只有我来帮助识别每个项目。它们确实完美无缺。

源表确实有以下重要行: 商品编号、变体 id、数量

using(SELECT *
      FROM   lbsysstock) AS LBS
ON EI.artikelnummer = lbs.artikelnummer
   AND EI.tecdocinfo = lbs.shop
WHEN matched AND LBS.shop = '0' THEN
  UPDATE SET EI.quantity = (SELECT Min(verfuegbar) - '1'
                            FROM   lbsysstock
                            WHERE  EI.artikelnummer = LBS.artikelnummer); 

我当前的问题是使用子选择查询更新项目的最后一部分。

例如项目编号 100001 确实有 3 个变体(黑色、绿色、蓝色)

Item number Item ID Quantity Color
100001 0 0 mother item
100001 1 66 black
100001 2 55 green
100001 3 77 blue

在这种情况下,我需要将绿色项目的数量减去-1。

【问题讨论】:

    标签: sql sql-server merge


    【解决方案1】:

    代码:

    DECLARE
      @Quantity
      TABLE
      (
        item_number     int,
        shop_id         smallint,
        quantity        tinyint,
        colour          varchar(10)
      )
    ;
    
    DECLARE
      @Destination
      TABLE
      (
        item_number     int,
        shop_id         tinyint,
        min_quantity    tinyint
      )
    ;
    
    INSERT INTO 
      @Quantity
    (
      item_number, shop_id, quantity, colour
    )
    VALUES
      ( 100001, 0, 0, 'mother' ),
      ( 100001, 1, 66, 'black' ),
      ( 100001, 2, 55, 'green' ),
      ( 100001, 3, 77, 'blue' )
    ;
    
    INSERT INTO 
      @Destination
    (
      item_number, shop_id, min_quantity
    )
    VALUES
      ( 100001, 0, 20 ),
      ( 100001, 2, 30 ),
      ( 100002, 0, 30 )
    ;
    
    SELECT
      *
    FROM
      @Quantity
    ;
    SELECT
      *
    FROM
      @Destination
    ;
    
    WITH
      cte_min_quantity
    (
      item_number,
      min_quantity
    )
    AS
    (
      SELECT
        item_number,
        Min( quantity ) -1
      FROM
        @Quantity
      WHERE
          shop_id <> 0
      GROUP BY
        item_number
    )
    /* -- debug
    SELECT
      *
    FROM
      cte_min_quantity
    */
    MERGE INTO @Destination AS Dest
      USING cte_min_quantity AS Src
        ON  Src.item_number = Dest.item_number
      WHEN MATCHED AND Dest.shop_id = 0
        THEN
        UPDATE SET
          Dest.min_quantity = Src.min_quantity
    ;
    
    SELECT
      *
    FROM
       @Destination
    ;
    

    算法:

    • 按 item_number 预聚合到来源的最小数量
    • 使用 CTE 准备数据
    • 将 Destination 加入 CTE 并仅在商店指示母商品时更新

    几点说明:

    • MERGE 比 INSERT / UPDATE 更强大,事务更友好,但代价是更难调试
    • CTE 更喜欢在内存中工作,如果太大会溢出到磁盘上的 tempdb 中

    【讨论】:

    • “MERGE 比 INSERT / UPDATE 更强大且事务友好,但代价是更难调试” - 关于事务完全不正确。没有提示,MERGE 不是原子的。
    • “CTE 更喜欢在记忆中工作”——你有具体的证据吗?我建议阅读:dba.stackexchange.com/questions/13112/…
    • @MitchWheat 链接很好,因此声明“更喜欢在内存中工作” - 就像任何数据收集一样,如果它不在内存中,则任何查询引擎都不会处理数据。因此,像 HANA 这样的 In Memory DMBS 引擎需要大量内存。如果数据变得太大,即使是表变量也会溢出到磁盘。主要证据来自大量执行计划调查——尤其是线轴具有指示性。见red-gate.com/simple-talk/wp-content/uploads/simplepod/…
    • 我知道什么是线轴,谢谢。此语句“与任何不在内存中的数据集合一样,任何查询引擎都不会处理数据”是不正确的。
    • 非常感谢您的回答@KnutBoehnert 遗憾的是我对 CTE 一无所知。难道没有一种获取所需数据的简化方法吗?我不想在现有表中插入任何数据。我对所有事情都使用 MS SQL Server Management Studio。也许您或其他任何人都可以如此友善,并逐步引导我找到解决方案。
    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多