2017-03-27 8 views
0

特定の製品の合計売上を確認しています。製品は、親製品の一部である場合もあれば、そうでない場合もあります。例えば、製品は親製品に含まれることがありますが、順番に親製品に含まれる可能性があります...複数のレベルの製品をベースにした製品のMYSQLの合計売上

実際に参照する必要があるテーブルは2つだけです。

Orders_Products

orders_products_id 
products_id 
products_quantity 

Layered_Products

parent_id 
subproduct_id 
subproduct_qty 

次のように私たちが使用したテーブルの内容は以下のとおりです。

Orders_Products

orders_products_id | products_id | products_qty 
-------------------+-------------+-------------- 
     8922   |  7232 |  1  
     8711   |  6823 |  2  
     8658   |  6823 |  1  
     8633   |  6823 |  2  
     8702   |  7538 |  1  
     8690   |  7538 |  1  
     8622   |  7538 |  2  

Layered_Products

parent_id + subproduct_id + subproduct_qty + 
----------+---------------+----------------+ 
    6823 +  7232  +  1  + 
    7538 +  6823  +  4  + 

このプロセスは、個々のクエリを使用することによって達成することができます。

SELECT IFNULL(SUM(products_qty),0) AS total_qty 
FROM orders_products 
WHERE products_id = '7232'; 

クエリ結果= total_qty = 1

SELECT lp.parent_id, lp.subproduct_qty, 
     IFNULL(SUM(op.products_qty) * lp.subproduct_qty,0) AS total_qty 
FROM layered_products lp 
LEFT JOIN orders_products op ON op.products_id = lp.parent_id 
WHERE lp.subproduct_id = '7232'; 

クエリ結果= PARENT_ID = 6823。 subproduct_qty = 1; total_qty = 5

SELECT lp.parent_id, lp.subproduct_qty, 
     IFNULL(SUM(op.products_qty) * lp.subproduct_qty * [prior select subproduct_qty],0) AS total_qty 
FROM layered_products lp 
LEFT JOIN orders_products op ON op.products_id = lp.parent_id 
WHERE lp.subproduct_id = [prior select parent_id]; 

クエリ結果= parent_id = 7538; subproduct_qty = 4; total_qtyすべてのクエリの= 16

合計= total_qty = 22

はしかし、私は1つのSELECTにすべてを取得しようとしています。あなたのSQLの達人の誰もがこれを達成するためのアイデアを持っていますか? 1週間以上作業していて、1レベルしか動かすことができません。 2番目の親レベルはまったく機能していません。試したサブクエリ、派生したクエリ、その他何かを見つけることができました。また、可能であれば追加のレベルを処理できるようにしたいと考えています。事前にありがとうございます...

答えて

0

MySQLは再帰クエリをサポートしていないため、これを行うためのきれいな方法はありません。

stored procを使用できますが、遅くなる可能性があります。

EDIT:...私の心の上にそれを行うための最も便利な方法は...ちょうどDBクエリ「再帰的WITH」どうするかのように

スタートです:私たちは、リスト「L」を持っています子をリストする要素が含まれています。

SELECT child_id WHERE parent_id IN (L) 

...結果は、リストL2に入る...

SELECT child_id WHERE parent_id IN (L2) 

...等...クエリが何も返さなくなるまで続けます。

煩わしくて迷惑ですが、それは唯一の方法です。アプリ内のストアドプロシージャでそれを行います...MySQLのストアドプロシージャの遅い速度と、ストアドプロシージャが一時テーブルを使用しなければならないという事実を考慮すると、ストアドプロシージャが実際にパフォーマンス上の利点を持つかどうかはわかりません。

があります。私はそれを使用して、どこを覚えていないかを覚えていない。

各要素に親のIDで作られたパスを与える。たとえば、次のようにパスがトリガーによって生成された場合は、別の親に子供がたくさんあり一つの要素を移動すると、そのすべての子のパスを更新する必要があるでしょうが、

relation table: 
parent_id child_id 
12   34 
34   567 

objects table (products here, but could be anything) 
obj_id path 
12  00000012 
34  00000012/00000034 
567  00000012/00000034/00000567 

さて、あなたは、日付までの経路を維持することができ、遅いかもしれません。

は今、要素の子を取得することによって行われます。

path LIKE '00000012/%' 

...そしてあなたがパス上のbtreeを持っている場合、これは割り出し可能です。超高速です。

しかし、あなたのケースでは後処理が必要なので、少し頭痛があります。また、それは非正規化し、ちょっと醜いです。あなたの選択!

+0

ありがとう、私が得た結果に基づいて考えたものです – user2465835

+0

私の投稿を編集しました。 – peufeu

関連する問題