0

MySQL データベースに 3 つの関連するテーブルがあります。

  • inventory_items は、倉庫内のアイテムのタイプを定義します
  • inventory_transactions は、追加または削除された在庫の数量を定義します
  • 場所は、在庫の場所を定義します

Inventory_transactions には、特定の場所で追加または削除された特定の inventory_item の数を格納する quantity_offset があります。

次のクエリは、global_quantity (指定された inventory_item_id のすべての quantity_offsets の合計) と、場所 ID を知っている限り、特定の場所に対して同じことを行う location_quantity を取得します。

SELECT sku, name, SUM(quantity_offset) AS global_quantity,
(
SELECT SUM(quantity_offset)
    FROM inventory_transactions
    WHERE inventory_items.inventory_item_id = inventory_transactions.inventory_item_id AND inventory_transactions.location_id = 1
) AS location_quantity
FROM inventory_items
JOIN inventory_transactions ON inventory_items.inventory_item_id = inventory_transactions.inventory_item_id
GROUP BY sku

最終的には、場所ごとに列が追加されるため、結果には次のような値が含まれる場合があります。

sku, name, global_quantity, denver_quantity, dallas_quantity, ft_wayne_quantity

私のフォールバックは、個々の inventory_item ページでこれを行うことです (在庫アイテムを知っていて、場所ごとにグループ化できる場合) が、1 つのクエリでそれを実行し、すべてを 1 つのテーブルに入れることができれば、非常に優れています。

最初は、サブクエリを反復処理できると思っていましたが、プログラムで (AS で) 列名を設定できませんでした。

ご提供いただけるご支援をよろしくお願いいたします。

4

3 に答える 3

1

余談ですが、SELECT リストでサブクエリを使用するのではなく、行が特定の場所からのものである場合に、条件付きで quantity_offset を返す式で SUM 集計を使用して同じ結果を得ることができます。また、inventory_transactions テーブルへの LEFT 外部結合を使用して、inventory_items の各行の行を確実に取得できるようにします。

SELECT i.sku
     , i.name
     , SUM(t.quantity_offset) AS global_quantity
     , SUM(IF(t.location_id = 1,t.quantity_offset,NULL)) AS location_1_quantity 
  FROM inventory_items i
  LEFT
  JOIN inventory_transactions t ON i.inventory_item_id = t.inventory_item_id
  GROUP BY i.sku

(それはあなたの質問に答えていませんが、私はあなたにそれを知らせたかったのです。)

あなたの質問に答えるには、まず、SELECT ステートメントが結果セットで返す列の数または型を動的に変更することはできません。返される列ごとに式を定義する必要があります。(特定の SELECT ステートメントを生成するために、SQL SELECT ステートメント テキストの生成を動的に行うこともできますが、その SELECT ステートメントによって返される列は SELECT ステートメントによって固定されます。)

比較的固定された location_id 値のセットがあり、指定した結果セットが必要な場合は、条件式の SUM を複数回繰り返します。場所ごと、または必要な場所のセットごとに 1 回です。

SELECT i.sku
     , i.name
     , SUM(t.quantity_offset) AS global_quantity
     , SUM(IF(t.location_id = 1,t.quantity_offset,NULL)) AS location_1_quantity 
     , SUM(IF(t.location_id = 2,t.quantity_offset,NULL)) AS location_2_quantity 
     , SUM(IF(t.location_id = 3,t.quantity_offset,NULL)) AS location_3_quantity 
     , SUM(IF(t.location_id IN (1,2,3),t.quantity_offset,NULL)) AS location_123_quantity 
     , SUM(IF(t.location_id = 4,t.quantity_offset,NULL)) AS location_4_quantity
  FROM inventory_items i
  LEFT
  JOIN inventory_transactions t ON i.inventory_item_id = t.inventory_item_id
  GROUP BY i.sku

返される列のセットが本当に動的である必要がある場合は、それらを列として返すことはまったくありません。代わりに、各場所の SUM(quantity_offset) を個別の行として返し、クライアント側で列単位の表現への変換を処理します。

于 2013-02-22T20:25:38.687 に答える
1

条件付き合計を使用する必要があります-これは私が知っている最も効率的な方法です(最速のクエリ):

SELECT sku, name, SUM(quantity_offset) AS global_quantity,
  sum(case when inventory_transactions.location_id = 1 then quantity_offset else 0 end) as  loc1_quantitity,
  sum(case when inventory_transactions.location_id = 2 then quantity_offset else 0 end) as loc2_quantitity,
  sum(case when inventory_transactions.location_id = 3 then quantity_offset else 0 end) as loc3_quantitity
FROM inventory_items JOIN inventory_transactions ON inventory_items.inventory_item_id = inventory_transactions.inventory_item_id
GROUP BY sku
于 2013-02-22T20:25:57.703 に答える
0

これを試して

   SELECT sku, name, SUM(quantity_offset) AS global_quantity,
       (
        SELECT SUM(quantity_offset)
         FROM inventory_transactions
           WHERE inventory_items.inventory_item_id = inventory_transactions.inventory_item_id AND inventory_transactions.location_id = 1
          AND location = denver) AS denver_quantity ,
        (
        SELECT SUM(quantity_offset)
         FROM inventory_transactions
           WHERE inventory_items.inventory_item_id = inventory_transactions.inventory_item_id AND inventory_transactions.location_id = 1
          AND location = dallas) AS dallas_quantity,
         (
        SELECT SUM(quantity_offset)
         FROM inventory_transactions
           WHERE inventory_items.inventory_item_id = inventory_transactions.inventory_item_id AND inventory_transactions.location_id = 1
          AND location = ft_wayne) AS ft_wayne_quantity
   FROM inventory_items
   JOIN inventory_transactions ON inventory_items.inventory_item_id = inventory_transactions.inventory_item_id
   GROUP BY sku

私は列名として使用したことに注意してlocationください。あなたが持っている場所の列名がわからないので、それを置き換えるだけです

于 2013-02-22T20:12:54.657 に答える