如何在 SUM 上求 MAX MySQL
How to find MAX over SUMs MySQL
考虑以下场景:
an Item has a Price
a Order contains Items
a Delivery contains Orders
我想查询每次发货,价格最高的订单,其中一个订单的价格是所含商品价格的总和。
一个足够简单的架构如下所示:
送货
d_id
订单
o_id
项目
i_id,价格
ItemsInOrder
o_id,i_id
交货订单
d_id,o_id
我卡在求和结果的点上,需要获得每次交付的最大订单数:
SELECT d_id,o_id,SUM(price)
from ItemsInOrder
natural join OrdersInDelivery
natural join Item
group by d_id,o_id
我应该如何从这里得到每个 d_id 都会出现一次并放在具有最大价格总和的 o_id 旁边?
不要使用 natural join
。它们是等待发生的错误,因为它们依赖于 table 中列的 名称 —— 甚至没有使用正确和明确定义的外键关系。请改用 on
或 using
。
这种类型的查询在 MySQL 中很痛苦,因为 MySQL 不支持 CTE(常见的 table 表达式)也不支持 window 函数。所以,查询比其他数据库更复杂:
select oid.d_id, o_id, SUM(price)
from OrdersInDelivery oid join
ItemsInOrder iio
using (o_id)
Item i
using (i_id)
group by d_id, o_id
having sum(price) = (select sum(iio2.price)
from ItemsInOrder iio2 join
Item i2
using (i_id)
where iio2.d_id = iio.d_id
group by iio2.o_id
order by sum(iio2.price) desc
limit 1
);
我正在分享我到目前为止得到的结果,这样任何人都可以继续帮助你,因为我现在需要离开去机场 :) 如果没有人弄明白的话,我明天会再试一次.
伙计们,这是一个具有挑战性的问题。
我已经在这里准备了一些样本:
http://sqlfiddle.com/#!9/d4fed2
我做的最新查询是:
SELECT d_id,OID.o_id,sumPrice
from OrdersInDelivery OID
join (SELECT IIO.o_id,SUM(I.price) as sumPrice
from ItemsInOrder IIO
join item I on I.i_id = IIO.i_id
group by IIO.o_id) IIO1 on OID.o_id = IIO1.o_id
祝你好运:)
您可以对自身使用左连接,调整连接条件和过滤器。
在这种方法中,您离开加入了 table 本身。当然,平等体现在组标识符中。
SELECT a.*
FROM (
SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price
FROM `OrdersInDelivery` oid
INNER JOIN `ItemsInOrder` iio USING (o_id)
INNER JOIN `Item` i USING (i_id)
GROUP BY d_id, o_id
) a
LEFT OUTER JOIN (
SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price
FROM `OrdersInDelivery` oid
INNER JOIN `ItemsInOrder` iio USING (o_id)
INNER JOIN `Item` i USING (i_id)
GROUP BY d_id, o_id
)b
ON a.d_id = b.d_id AND a.sum_price < b.sum_price
WHERE b.d_id IS NULL AND b.o_id IS NULL;
看看 SQL fiddle 中的这个查询:http://sqlfiddle.com/#!9/d5c04d/1
在这种情况下,建议使用 TEMPORARY TABLE
:
CREATE TEMPORARY TABLE OrderSummary(
SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price
FROM `OrdersInDelivery` oid
INNER JOIN `ItemsInOrder` iio USING (o_id)
INNER JOIN `Item` i USING (i_id)
GROUP BY d_id, o_id
);
CREATE TEMPORARY TABLE OrderSummary2(
SELECT * FROM OrderSummary
);
SELECT a.*
FROM OrderSummary a
LEFT OUTER JOIN OrderSummary2 b
ON a.d_id = b.d_id AND a.sum_price < b.sum_price
WHERE b.d_id IS NULL AND b.o_id IS NULL;
感谢您的所有回答,但其中 none 正是我要找的。我终于找到了我要找的东西,我选择的方法如下:
SELECT d_id,o_id,sum_price
FROM (
SELECT d_id,o_id,SUM(price) as sum_price
from ItemsInOrder
natural join OrdersInDelivery
natural join Item
group by d_id,o_id
order by d_id,sum_price desc
) as sums
GROUP BY d_id
考虑以下场景:
an Item has a Price
a Order contains Items
a Delivery contains Orders
我想查询每次发货,价格最高的订单,其中一个订单的价格是所含商品价格的总和。
一个足够简单的架构如下所示:
送货
d_id
订单
o_id
项目
i_id,价格
ItemsInOrder
o_id,i_id
交货订单
d_id,o_id
我卡在求和结果的点上,需要获得每次交付的最大订单数:
SELECT d_id,o_id,SUM(price)
from ItemsInOrder
natural join OrdersInDelivery
natural join Item
group by d_id,o_id
我应该如何从这里得到每个 d_id 都会出现一次并放在具有最大价格总和的 o_id 旁边?
不要使用 natural join
。它们是等待发生的错误,因为它们依赖于 table 中列的 名称 —— 甚至没有使用正确和明确定义的外键关系。请改用 on
或 using
。
这种类型的查询在 MySQL 中很痛苦,因为 MySQL 不支持 CTE(常见的 table 表达式)也不支持 window 函数。所以,查询比其他数据库更复杂:
select oid.d_id, o_id, SUM(price)
from OrdersInDelivery oid join
ItemsInOrder iio
using (o_id)
Item i
using (i_id)
group by d_id, o_id
having sum(price) = (select sum(iio2.price)
from ItemsInOrder iio2 join
Item i2
using (i_id)
where iio2.d_id = iio.d_id
group by iio2.o_id
order by sum(iio2.price) desc
limit 1
);
我正在分享我到目前为止得到的结果,这样任何人都可以继续帮助你,因为我现在需要离开去机场 :) 如果没有人弄明白的话,我明天会再试一次.
伙计们,这是一个具有挑战性的问题。
我已经在这里准备了一些样本: http://sqlfiddle.com/#!9/d4fed2
我做的最新查询是:
SELECT d_id,OID.o_id,sumPrice
from OrdersInDelivery OID
join (SELECT IIO.o_id,SUM(I.price) as sumPrice
from ItemsInOrder IIO
join item I on I.i_id = IIO.i_id
group by IIO.o_id) IIO1 on OID.o_id = IIO1.o_id
祝你好运:)
您可以对自身使用左连接,调整连接条件和过滤器。 在这种方法中,您离开加入了 table 本身。当然,平等体现在组标识符中。
SELECT a.*
FROM (
SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price
FROM `OrdersInDelivery` oid
INNER JOIN `ItemsInOrder` iio USING (o_id)
INNER JOIN `Item` i USING (i_id)
GROUP BY d_id, o_id
) a
LEFT OUTER JOIN (
SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price
FROM `OrdersInDelivery` oid
INNER JOIN `ItemsInOrder` iio USING (o_id)
INNER JOIN `Item` i USING (i_id)
GROUP BY d_id, o_id
)b
ON a.d_id = b.d_id AND a.sum_price < b.sum_price
WHERE b.d_id IS NULL AND b.o_id IS NULL;
看看 SQL fiddle 中的这个查询:http://sqlfiddle.com/#!9/d5c04d/1
在这种情况下,建议使用 TEMPORARY TABLE
:
CREATE TEMPORARY TABLE OrderSummary(
SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price
FROM `OrdersInDelivery` oid
INNER JOIN `ItemsInOrder` iio USING (o_id)
INNER JOIN `Item` i USING (i_id)
GROUP BY d_id, o_id
);
CREATE TEMPORARY TABLE OrderSummary2(
SELECT * FROM OrderSummary
);
SELECT a.*
FROM OrderSummary a
LEFT OUTER JOIN OrderSummary2 b
ON a.d_id = b.d_id AND a.sum_price < b.sum_price
WHERE b.d_id IS NULL AND b.o_id IS NULL;
感谢您的所有回答,但其中 none 正是我要找的。我终于找到了我要找的东西,我选择的方法如下:
SELECT d_id,o_id,sum_price
FROM (
SELECT d_id,o_id,SUM(price) as sum_price
from ItemsInOrder
natural join OrdersInDelivery
natural join Item
group by d_id,o_id
order by d_id,sum_price desc
) as sums
GROUP BY d_id