使用SUM和COUNT进行多表查询

时间:2014-07-30 14:00:47

标签: mysql sql count sum multiple-tables

我正在努力写一个(对我!)复杂的查询,它将计算出售的单位总数,从两个单独的表中提取数据。我正在使用MySQL。

第一个表是一个简单的'order_contents'表(在我的示例中为sale_ord_contents),其中包含item_id和销售数量。某些项目可能是程序集,在这种情况下,它们的内容将存储在另一个表sale_ord_assembly_contents中,以及每个子组件的数量。在我的例子中,唯一的“组装”是水果篮。我已经注意到其中一个Fruit Basket条目的销售数量为(2),这意味着它的所有内容都应该将它们的数量乘以2。

enter image description here

我的目标是通过在两张桌子之间销售的累积数量找到20种最常见的物品。我最挣扎的部分是如何处理子组件的值乘以sale_ord_contents表中父组件的数量。

我已编写此查询来处理sale_ord_contents计算,但我无法加入sale_ord_assembly_contents表中的数据......

SELECT
   item_id, name, sku,
   SUM(quantity) AS purchases
FROM
   sale_ord_contents
GROUP BY
   item_id
ORDER BY purchases DESC
LIMIT 20

我会在PHP中做得更好,或者这在MySQL中是否可行?如果是这样,SQL大师可以帮助我编写一个提供所需结果的查询吗?谢谢!

3 个答案:

答案 0 :(得分:1)

更新了我的回答,请再试一次以下内容:

SELECT
    IF (soac.item_id IS NULL, soc.item_id, soac.item_id) as item_id,
    IF (soac.name IS NULL, soc.name, soac.name) as name,
    SUM(soc.quantity * COALESCE(soac.quantity, 1)) AS total_sold
FROM
    sale_ord_contents soc
        LEFT OUTER JOIN sale_ord_assembly_contents soac
           ON soac.order_item_id = soc.id
GROUP BY
    IF (soac.quantity IS NULL, soc.item_id, soac.item_id),
    IF (soac.name IS NULL, soc.name, soac.name)
ORDER BY total_sold DESC LIMIT 20

答案 1 :(得分:0)

是的,它的可行性和查询执行时间也较少,因为您限制了返回的行数。请在mysql workbench中检查查询优化器以获取查询响应时间:)。在php中为循环写太多会降低页面响应时间,并且执行时间会更多。因此,最好在PHP代码中编写高级应用程序查询,以便为您的网页获得更好的响应时间:)

答案 2 :(得分:0)

解决问题的关键是左连接。基本上它的作用是匹配左侧表格和left join右侧表格之间的值。如果右侧的表格没有任何正确匹配的值,则会插入null。在sale_ord_contents和sale_ord_assembly_contents之间执行左连接将产生如下结果:

Sale_ord_contents_name | quantity | sale_ord_assembly_contents_name | quantity
apple                  | 5        |    null                         |  null
fruitbasket 1          | 1        |    apple                        |  3
fruitbasket 1          | 1        |    orange                       |  1

这些数字与您提供的示例不符,但您明白了。这正是您需要找到正确的数字。

下一个重要的关键字是coalesce。这样做是通过您提供的项目列表并返回非空的第一个值。因此,如果我使用coalesce(sale_ord_assembly_contents_name,sale_ord_contents_name),对于上面的示例,将忽略程序集表中的null并返回apple。然后,由于接下来的两行存在程序集名称,因此apple和orange将是coalesce返回的值。

我相信您需要以下查询:

SELECT
   coalesce(soa.item_id, so.item_id) as item_id,
   coalesce(soa.name, so.name) as name,
   so.sku,
   SUM(so.quantity * coalesce(soa.quantity, 1)) AS purchases
FROM
   sale_ord_contents so
   left join sale_ord_assembly_contents soa
   on so.id = soa.order_item_id
GROUP BY
   item_id, name, so.sku
ORDER BY purchases DESC
LIMIT 20