我正在努力写一个(对我!)复杂的查询,它将计算出售的单位总数,从两个单独的表中提取数据。我正在使用MySQL。
第一个表是一个简单的'order_contents'表(在我的示例中为sale_ord_contents
),其中包含item_id和销售数量。某些项目可能是程序集,在这种情况下,它们的内容将存储在另一个表sale_ord_assembly_contents
中,以及每个子组件的数量。在我的例子中,唯一的“组装”是水果篮。我已经注意到其中一个Fruit Basket条目的销售数量为(2),这意味着它的所有内容都应该将它们的数量乘以2。
我的目标是通过在两张桌子之间销售的累积数量找到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大师可以帮助我编写一个提供所需结果的查询吗?谢谢!
答案 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