MYSQL基于多级产品的产品总销售额

时间:2017-03-27 14:43:53

标签: mysql select product

希望确定特定产品的总销售额。该产品可能是也可能不是母产品的一部分。例如,产品可能包含在一组母产品中,而母产品又可以包含在母产品中,而母产品又可以......等等......

实际上只需要引用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

但是,我试图将所有内容都集成到一个SELECT中。你们中的任何一位SQL专家都知道如何实现这一目标吗?已经工作了一个多星期了,只能达到一个级别。第二个父级别根本不起作用。尝试过子查询,派生查询以及我能找到的任何其他内容。此外,如果可能的话,希望能够处理更多级别。提前谢谢......

1 个答案:

答案 0 :(得分:0)

MySQL不支持递归查询,因此没有干净的方法来执行此操作。

您可以使用stored proc,但可能会很慢。

编辑:最方便的方式来做到这一点......就像数据库的做法一样" WITH RECURSIVE"查询...

开始:我们有一个清单" 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,这是可索引的。它非常快。

但是你需要在你的情况下进行一些后处理,所以会有一点头疼。而且,它非规范化,有点难看。你的选择!