如何在 MySQL 中使用嵌套查询完成订购数量之前的 SELECT 和 INSERT

问题描述

Database Sample Picture

继续查看上图,我想运行查询直到满足 $orderQty。图中上表为products,下表为temp_salesee,这是运行我的代码后的结果。
这是我的代码

    $orderQty = 22;
    $trID     = round(microtime(true) * 1000);
    $proID    = 1;

$con->begin_transaction();
$stmt = $con->prepare("
INSERT INTO `temp_salesee` (
    SELECT
         null,$trID,`pid`,`pur_price`,(CASE
                WHEN qty_avbl <= $orderQty THEN qty_avbl
                WHEN qty_avbl >= $orderQty THEN $orderQty
                else 0
            END),`batch_number`
        FROM `products`
        WHERE `pid` = ?
        ORDER BY `batch_number` ASC
)
        ");

$stmt->bind_param('s',$proID);
$stmt->execute();
$con->commit();

在第 3 行的 temp_salesee 中,qty 应为 2,这样总计 qty 将等于 $orderQty 此时查询应停止,第 4、第 5 行不应被插入。如果 $orderQty 小于 qty_avbl,如 products 表的第一行所示,则只有第一行应插入 temp_salesee 表中,其中 qty 5.
谢谢

解决方法

老实说,我只是放弃了使用“智能查询”的想法,而使用普通的程序循环。 “搞定。” 准备 SELECTINSERT 语句句柄,开始事务,然后运行 ​​SELECT。然后,根据需要 INSERT 次。最后,COMMIT

虽然毕竟可能有一种“聪明”的方法可以做到这一点,但它可能不值得寻找。而且,它可能不会显而易见,这可能意味着随着需求(不可避免地......)的变化,很难继续前进。所以,我会说,“减少损失。”

,

我希望并想象必须有一个更高效的解决方案,但无论如何,请考虑以下几点:

架构(MySQL v8.0)

DROP TABLE IF EXISTS product_batches;

CREATE TABLE product_batches
(batch_number SERIAL PRIMARY KEY,product_id INT NOT NULL,quantity_available INT NOT NULL
);

INSERT INTO product_batches VALUES
( 1,1,15),( 3,5),( 7,20),(10,30),(11,50);

查询 #1

SELECT batch_number,product_id
  FROM 
     ( SELECT x.*,COALESCE(LAG(SUM(y.quantity_available),1) OVER (ORDER BY batch_number),0) running
         FROM product_batches x 
         JOIN product_batches y
           ON y.product_id = x.product_id 
          AND y.batch_number <= x.batch_number 
        GROUP 
           BY x.batch_number
      ) a 
  WHERE running <=22;
batch_number product_id
1 1
3 1
7 1

View on DB Fiddle

编辑:

没有广泛测试,但对于旧版本,我认为你可以做这样的事情(虽然性能可能很糟糕),所以认真考虑升级:

   SELECT x.*,z.total - SUM(y.quantity_available) running
     FROM product_batches x 
     JOIN product_batches y
       ON y.product_id = x.product_id 
      AND y.batch_number >= x.batch_number
     JOIN (SELECT product_id,SUM(quantity_available) total FROM product_batches GROUP BY product_id) z
       ON z.product_id = x.product_id
    GROUP 
       BY x.batch_number
   HAVING running <= 22;

编辑 2:

也许这样更清楚:

SELECT x.*,GREATEST(SUM(y.quantity_available)-22,0) balance
     FROM product_batches x 
     JOIN product_batches y
       ON y.product_id = x.product_id 
      AND y.batch_number <= x.batch_number
    GROUP 
       BY x.batch_number
   HAVING balance < quantity_available

https://www.db-fiddle.com/f/DHED9dyxR2gMWaStyBZbN/0