Mysql 基于时间戳和库存级别的SQL连接相同的表

Mysql 基于时间戳和库存级别的SQL连接相同的表,mysql,sql,join,Mysql,Sql,Join,我正在处理每分钟告诉我当前库存水平并将其存储在数据库中的库存数据 我想找到item_计数下降到0的每个实例,使用时间戳获取该行,然后将其连接到item_计数上升到0以上的下一行。这将告诉我该产品缺货多长时间 我提出了以下内容,但它没有返回任何内容 SELECT `inventories`.* from `inventories` inner join (SELECT id, item_count, pusher_id, created_at as in_stock_at

我正在处理每分钟告诉我当前库存水平并将其存储在数据库中的库存数据

我想找到item_计数下降到0的每个实例,使用时间戳获取该行,然后将其连接到item_计数上升到0以上的下一行。这将告诉我该产品缺货多长时间

我提出了以下内容,但它没有返回任何内容

SELECT `inventories`.* from `inventories` inner join 
    (SELECT id, item_count, pusher_id, created_at as in_stock_at
                FROM inventories
                GROUP BY pusher_id) inv2 
ON `inventories`.`created_at` < `inv2`.`in_stock_at` 
    AND `inv2`.`item_count` > `inventories`.`item_count` 
    AND `inventories`.`pusher_id` = `inv2`.`pusher_id` 
WHERE `inventories`.`item_count` <= 0 
    AND `inventories`.`product_id`=9
数据::

INSERT INTO `inventories` (`id`, `client_id`, `pusher_id`, `product_id`, `reader_id`, `tags_blocked`, `item_count`, `active`, `created_at`, `updated_at`, `deleted_at`) VALUES
    (1, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 04:45:47', '2015-10-23 04:45:47', NULL),
    (2, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 04:55:47', '2015-10-23 04:45:47', NULL),
    (3, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 05:05:47', '2015-10-23 04:45:47', NULL),
    ...
    (10, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 06:15:47', '2015-10-23 04:45:47', NULL),
    (11, 1, 1, 9, 1, 10.00, 10.00, 1, '2015-10-22 06:25:47', '2015-10-23 04:45:47', NULL),
    (12, 1, 1, 9, 1, 9.00, 9.00, 1, '2015-10-22 06:35:47', '2015-10-23 04:45:47', NULL),
    (13, 1, 1, 9, 1, 8.00, 8.00, 1, '2015-10-22 06:45:47', '2015-10-23 04:45:47', NULL),
期望结果::

根据上面的数据,我想将ID为1的行和ID为11的行连接起来。 1.在表格中搜索item_count=0的第一行,查找具有相同产品_id和推送者_id且item_count>0且created_at>firstRow.created_at的行。把他们连在一起。 然后,查找此事件的下一个实例


我希望这能澄清问题。

翻译成SQL并不是那么难,但性能可能很差。这将为您获取产品返回库存时的时间戳:

SELECT inv.*,
 ( SELECT MIN(`inv2`.`in_stock_at`)
   FROM inventories AS inv2
   WHERE inv2.`product_id` = inv.`product_id`   -- same product
     AND inv2.`pusher_id` = `inv`.`pusher_id`   -- same pusher
     AND `inv2`.`created_at` > inv.`created_at` -- later timestamp
     AND `inv2`.`item_count` > 0                -- in stock
 ) AS inStockAgain_at
from `inventories` AS inv
WHERE inv.`item_count` <= 0   -- out of stock
 -- AND inv.`product_id`=9
编辑:

删除库存为零的连续行更为复杂:

SELECT inv.*, dt.inStockAgain_at
FROM inventories AS inv
JOIN
 ( 
   SELECT product_id, pusher_id, 
      MIN(created_at) AS min_created_at,
     inStockAgain_at
   FROM
    (
      SELECT product_id, pusher_id, created_at,
       ( SELECT MIN(inv2.created_at)
         FROM inventories AS inv2
         WHERE inv2.product_id = inv.product_id -- same product
           AND inv2.pusher_id = inv.pusher_id   -- same pusher
           AND inv2.created_at > inv.created_at -- later timestamp
           AND inv2.item_count > 0              -- in stock
       ) AS inStockAgain_at
      FROM inventories AS inv
      WHERE inv.item_count <= 0  
    ) AS dt
   GROUP BY product_id, pusher_id, inStockAgain_at
 ) AS dt
ON inv.product_id = dt.product_id
AND inv.pusher_id = dt.pusher_id 
AND inv.created_at = dt.min_created_at 

请参见添加样本数据和所需结果。您的查询中有pusher_id之类的内容,这毫无意义。这种方法行不通,因为您需要将库存水平降至零的行与库存水平非零的下一行配对。我很有信心在mysql中很难做到这一点。如果是MS SQL,则可以使用CTE实现,我相信其他DBMS也应该有可行的解决方案。我希望在数据库外部或存储过程中实现这一点。这可以工作99.9%。我唯一想更改/修复的是以下内容:这将返回第1行和第11行在1处加入库存,在第11行有库存,但它返回第2行和第11行连接,因为10分钟后它仍然缺货。有没有办法让它在继续搜索下一行的项目计数为0时跳到第11行?@KiaiFighter:我增强了查询并添加了一个fiddle。非常好=D这正是我要找的!现在我只需要把它分解一下,以确保我理解它=
SELECT inv.*, dt.inStockAgain_at
FROM inventories AS inv
JOIN
 ( 
   SELECT product_id, pusher_id, 
      MIN(created_at) AS min_created_at,
     inStockAgain_at
   FROM
    (
      SELECT product_id, pusher_id, created_at,
       ( SELECT MIN(inv2.created_at)
         FROM inventories AS inv2
         WHERE inv2.product_id = inv.product_id -- same product
           AND inv2.pusher_id = inv.pusher_id   -- same pusher
           AND inv2.created_at > inv.created_at -- later timestamp
           AND inv2.item_count > 0              -- in stock
       ) AS inStockAgain_at
      FROM inventories AS inv
      WHERE inv.item_count <= 0  
    ) AS dt
   GROUP BY product_id, pusher_id, inStockAgain_at
 ) AS dt
ON inv.product_id = dt.product_id
AND inv.pusher_id = dt.pusher_id 
AND inv.created_at = dt.min_created_at