8

単なるselectステートメントを使用して以下を実行できるかどうかはわかりませんが、2つのテーブルがあります(問題に必要なデータで切り捨てられています)。

在庫品目

  • id int (プライマリ)
  • 数量整数

在庫- 在庫品目の在庫の変更が含まれます (在庫履歴)

  • id int (プライマリ)
  • inventory_item_id int (FOREIGN KEY)
  • 数量整数
  • 作成日時

在庫数量は在庫の変動であり、在庫品目の数量はその品目の現在の数量です。

runningのすべてが 0 を返します

SELECT
inventory_item.id,
(inventory_item.quantity - SUM(stock.quantity)) AS running
FROM
    stock
        JOIN
    inventory_item ON stock.inventory_item_id = inventory_item.id
GROUP BY inventory_item.id

質問

さて、私が知りたいのは、SELECTを使用してinventory_itemの実行中の数量がゼロになる在庫テーブルのすべての日付を選択することは可能ですか?

これは、1 つのアイテムの在庫データをすべて選択し、現在の在庫アイテムの数量から在庫数量を個別に差し引くだけで、プログラムで実行できることを知っています。これにより、在庫の変更が発生する前の数量が得られます。SELECTでこれを行うことはできますか?

4

5 に答える 5

5

(更新) inventory_item_id と created の特定の組み合わせに対して複数のレコードが存在しないと仮定して、次を試してください。

SELECT i.id,
       s.created,
       i.quantity - COALESCE(SUM(s2.quantity),0) AS running
FROM inventory_item i
JOIN stock s ON s.inventory_item_id = i.id
LEFT JOIN stock s2 ON s2.inventory_item_id = i.id and s.created < s2.created
GROUP BY i.id, s.created
HAVING running=0
于 2013-07-01T17:22:59.610 に答える
2

これを行う最も論理的な方法は、累積合計を使用することです。しかし、MySQL はそれをサポートしていません。

私の意見では、最も明確なアプローチは、相関サブクエリを使用して実行中の数量を取得することです。次に、それがwhereどこにあるかを選択するのは節の簡単な問題です0:

select i.*
from (select i.*,
             (select SUM(i2.inventory)
              from inventory i2
              where i2.inventory_item_id = i.inventory_item_id and
                    i2.created <= i.created
             ) as RunningQuantity
      from inventory i
     ) i
 where RunningQuantity = 0;
于 2013-07-01T17:25:47.570 に答える
2

私の見解:

select
    inventory_item_id `item`,
    created `when`
from
    (select 
         @total := CASE WHEN @curr <> inventory_item_id
                   THEN quantity
                   ELSE @total+quantity END as running_total,
         inventory_item_id,
         created,                   
         @curr := inventory_item_id
     from
         (select @total := 0) a
         (select @curr  := -1) b
         (select inventory_item_id, created, quantity from stock order by inventory_item_id, created asc) c
     ) running_total
where running_total.running_total = 0;

これには、在庫テーブルへのパスを 1 回だけ与える必要があるという相対的な利点があります。サイズとその上のインデックスに応じて、それが良い場合とそうでない場合があります。

于 2013-07-01T17:28:38.090 に答える
2

これはこれに対する単純なアプローチだと思います。

SELECT inventory_item.id, stock.created

FROM   inventory_item

       JOIN stock ON stock.inventory_item_id = inventory_item.id

WHERE  (SELECT SUM(quantity) FROM stock WHERE created <= stock.created) = 0
于 2013-07-01T17:30:07.483 に答える
2

ここで見つかったフラグが付けられる現在の合計に基づいて、同様の応答がありました...

MySQL @variables を使用できますが、データはアクティビティのデータによって事前にクエリおよび順序付けする必要があります...次に、負の原因となる各行にフラグを設定し、それらのみを保持します。何かのようなもの

select 
      PreQuery.*
   from 
      ( select
              s.id,
              s.created,
              @runBal := if( s.id = @lastID, @runBal - quantity, @i.quantity ) as CurBal,
              @lastID := s.id as IDToCompareNextEntry
           from
              stock s
                 join inventory_item ii
                    on s.inventory_item_id = ii.id,
              (select @lastID := -1,
                      @runBal := 0 ) sqlvars
           order by
              s.id,
              s.created DESC ) PreQuery
   where
      PreQuery.CurBal < 0

このように、各インベントリ アイテムについて、作成日で逆方向に動作します (ID ごとに作成された降順)。そのため、在庫 ID が変更されたら、在庫テーブルの「数量」フィールドを見て、使用済み在庫の集計を開始します。処理された最後のレコードと同じ ID の場合は、実行中の残高を使用して、その在庫エントリの数量を差し引くだけです。

于 2013-07-01T17:31:33.240 に答える