繁体   English   中英

从上一行MySQL减去数量

[英]Subtract Quantity From Previous Row MySQL

在这方面遇到困难。 我在PHP中回显了这些数据,但我认为在MySQL中进行查询会更好。

这是我的桌子:

在此处输入图片说明

我的查询(错误):

SELECT i1.Quantity,
i1.timestamp,
(i2.Quantity - i1.Quantity) as sold_qty 
FROM InventoryTest_history i1
INNER JOIN
InventoryTest_history i2 ON i2.id = i1.id + 1
WHERE i1.SKU = '(L) U-Joint'

仅检索两行,并且sold_qty错误。

在此处输入图片说明

我试图达到的结果将如下所示:

Quantity |  timestamp   | sold_qty
985         2016-12-27      0  
960         2016-12-28      25
955         2016-12-29      5

有人可以帮忙吗?

一种选择是使用相关子查询。 对于大集合,这当然不是最有效的方法,但是对于返回的行数有限,它是可行的。

您似乎需要一个序列来处理和返回行,但是没有ORDER BY子句。 从示例数据来看,它看起来像是按timestamp列升序,按Quantity列降序和/或按id升序。 我们只是在猜测。

假设序列是通过timestampid ,并且假设(timestamp,id)元组是唯一的...这些是相当合理的假设,但它们只是假设,并且是相当大的假设...

SELECT ih.Quantity
     , ih.timestamp

     , IFNULL(
                 ( SELECT pr.Quantity
                     FROM InventoryTest_history pr
                    WHERE pr.SKU = ih.SKU
                      AND pr.timestamp <= ih.timestamp
                      AND (pr.timestamp < ih.timestamp OR pr.id < ih.id )
                    ORDER BY pr.SKU DESC, pr.timestamp DESC, pr.id DESC
                    LIMIT 1
                 )
                 - ih.Quantity
       ,0) AS sold_qty

  FROM InventoryTest_history ih
 WHERE ih.SKU = '(L) U-Joint'
 ORDER BY ... 

为了获得最佳性能和最佳性能,我们希望覆盖索引可用于相关子查询,作为适当索引的示例:

 ... ON InventoryTest_history (SKU, timestamp, id, quantity) 

如果应认为行不是按(timestamp,id)排序,则需要修改ORDER BY和子查询的WHERE子句中的条件。


这只是一种可能的方法。 还有其他查询模式将返回等效结果。

您也可以不使用JOIN表就使用它:out SELECT仅用于隐藏一些列。

SELECT Quantity, `timestamp`, sold_qty
FROM (
    SELECT i.*,
    @sold_qty := GREATEST(@last_qty - i.`Quantity`,0) as sold_qty,
    @last_qty := i.`Quantity` as last_qty
    FROM InventoryTest_history i
    CROSS JOIN ( SELECT @last_qty := '', @sold_qty := 0) as init
    ORDER BY `timestamp`
    ) as result;

样品

mysql> SELECT * from InventoryTest_history;

+----+-------------+----------+---------------------+
| id | SKU         | Quantity | timestamp           |
+----+-------------+----------+---------------------+
|  1 | (L) U-Joint |      985 | 2016-12-27 10:08:58 |
|  2 | (L) U-Joint |      960 | 2016-12-28 10:09:52 |
|  3 | (L) U-Joint |      955 | 2016-12-29 16:01:02 |
+----+-------------+----------+---------------------+
3 rows in set (0,02 sec)

mysql> SELECT Quantity, `timestamp`, sold_qty
    -> FROM (
    ->     SELECT i.*,
    ->     @sold_qty := GREATEST(@last_qty - i.`Quantity`,0) as sold_qty,
    ->     @last_qty := i.`Quantity` as last_qty
    ->     FROM InventoryTest_history i
    ->     CROSS JOIN ( SELECT @last_qty := '', @sold_qty := 0) as init
    ->     ORDER BY `timestamp`
    ->     ) as result;
+----------+---------------------+----------+
| Quantity | timestamp           | sold_qty |
+----------+---------------------+----------+
|      985 | 2016-12-27 10:08:58 |        0 |
|      960 | 2016-12-28 10:09:52 |       25 |
|      955 | 2016-12-29 16:01:02 |        5 |
+----------+---------------------+----------+
3 rows in set (0,00 sec)

mysql> SELECT i.*,
    -> @sold_qty := GREATEST(@last_qty - i.`Quantity`,0) as sold_qty,
    -> @last_qty := i.`Quantity` as last_qty
    -> FROM InventoryTest_history i
    -> CROSS JOIN ( SELECT @last_qty := '', @sold_qty := 0) as init
    -> ORDER BY `timestamp`;
+----+-------------+----------+---------------------+----------+----------+
| id | SKU         | Quantity | timestamp           | sold_qty | last_qty |
+----+-------------+----------+---------------------+----------+----------+
|  1 | (L) U-Joint |      985 | 2016-12-27 10:08:58 |        0 |      985 |
|  2 | (L) U-Joint |      960 | 2016-12-28 10:09:52 |       25 |      960 |
|  3 | (L) U-Joint |      955 | 2016-12-29 16:01:02 |        5 |      955 |
+----+-------------+----------+---------------------+----------+----------+
3 rows in set (0,00 sec)

mysql>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM