我正在尝试创建订单的摘要报告,但无法在单个查询中提取所有必需的数据。
我想提取的数据:
订单表(本例简化)
| orderId | deliveryTotal | total |
|---------|---------------|-------|
| 1 | 5 | 15 |
| 2 | 5 | 15 |
| 3 | 7.50 | 27.50 |
订单商品表
| orderItemId | orderId | productId | salePrice | quantity |
|-------------|---------|-----------|-----------|----------|
| 1 | 1 | 1 | 10 | 1 |
| 2 | 2 | 1 | 10 | 1 |
| 3 | 3 | 1 | 10 | 1 |
| 4 | 3 | 2 | 10 | 1 |
我目前提取此数据的查询是
SELECT
SUM(i.salePrice * i.quantity) as subtotal,
SUM(DISTINCT o.deliveryTotal) as deliveryTotal,
COUNT(DISTINCT o.orderId) as orders,
SUM(i.quantity) as quantity
FROM orderItems i
INNER JOIN orders o ON o.orderId = i.orderId
这导致正确的小计,订单计数和数量总和。但是当我在17.50之后,交付总额返回12.50。如果我SUM(o.deliveryTotal)
,它将返回25。
编辑:期望的结果
| subtotal | deliveryTotal | orders | quantity |
|----------|---------------|--------|----------|
| 40.00 | 17.50 | 3 | 4 |
答案 0 :(得分:4)
由于加入,SUM(DISTINCT deliveryTotal)
聚合应用于包含值5, 5, 7.5, 7.5
(不同5 + 7.5 = 12.5
)的行集。
如果您只是
,SUM()
行动的行就会变得更加明显
SELECT o.*
FROM orderItems i
INNER JOIN orders o ON o.orderId = i.orderId
相反,您要求SUM()
中所有值的deliveryTotal
,无论他们在与orderItems
的加入中的位置如何。这意味着您需要在不同的级别应用聚合。
由于您不打算稍后添加GROUP BY
,最简单的方法是使用子选择,其目的只是在整个表中获取SUM()
。
SELECT
SUM(i.salePrice * i.quantity) as subtotal,
-- deliveryTotal sum as a subselect
(SELECT SUM(deliveryTotal) FROM orders) as deliveryTotal,
COUNT(DISTINCT o.orderId) as orders,
SUM(i.quantity) as quantity
FROM orderItems i
INNER JOIN orders o ON o.orderId = i.orderId
通常不鼓励使用子选择,但子选择不会有显着的性能损失,与使用连接的替代方法没有区别。无论如何,计算必须在与现有连接的单独聚合上完成。其他方法会在CROSS JOIN
子句中放置子查询FROM
,它执行我们在子选择中放置的相同内容。表现会一样。
答案 1 :(得分:1)
在内部选择中选择每个订单而不是总结
Select
SUM(subtotal) as subtotal,
sum(deliveryTotal) as deliveryTotal,
count(1) as orders,
sum(quantity) as quantity
from (
SELECT
SUM(i.salePrice * i.quantity) as subtotal,
o.deliveryTotal as deliveryTotal,
SUM(i.quantity) as quantity
FROM orders o
INNER JOIN orderItems i ON o.orderId = i.orderId
group by o.orderId) as sub
答案 2 :(得分:0)
以下查询确切地显示了您的需求
SELECT SUM(conctable.subtotal),
SUM(conctable.deliveryTotal),
SUM(conctable.orders),
SUM(conctable.quantity) from
(SELECT SUM(i.salePrice * i.quantity) as subtotal,
o.deliveryTotal as deliveryTotal,
COUNT(DISTINCT o.orderId) as orders,
SUM(i.quantity) as quantity
FROM orderItems i
JOIN orders o ON o.orderId = i.orderId group by i.orderid) as conctable;
答案 3 :(得分:0)
https://tiaashish.wordpress.com/2014/01/31/mysql-sum-for-distinct-rows-with-left-join/
这是一篇博客文章,准确显示了我在寻找什么。也许这也可以帮助其他人。
公式如下:
SUM(o.deliveryTotal) * COUNT(DISTINCT o.orderId) / COUNT(*)