[英]SQL question about GROUP BY
我已经使用 SQL 几年了,这种类型的问题到处出现,我还没有找到答案。 但也许我一直在寻找错误的地方——我真的不知道该怎么称呼它。
为简洁起见,假设我有一个包含 3 列的表:Customer、Order_Amount、Order_Date。 每个客户可能有多个订单,每个订单有一行,其中包含金额和日期。
我的问题:SQL 中是否有一种简单的方法来获取每个客户最大订单的日期?
我可以通过执行以下操作来获得每个客户(以及哪个客户做出的)的最大订单金额:
SELECT Customer, MAX(Order_Amount) FROM orders GROUP BY Customer;
但我也想得到最大订单的日期,我还没有想出一个容易得到的方法。 我原以为这将是数据库的常见问题类型,因此在 SQL 中很容易做到,但我还没有找到一种简单的方法来做到这一点。 一旦我将 Order_Date 添加到 select 的列列表中,我需要将其添加到 Group By 子句中,我认为这不会给我想要的东西。
没有捷径……最简单的方法可能是加入子查询:
SELECT
*
FROM
orders JOIN
(
SELECT Customer, MAX(Order_Amount) AS Max_Order_Amount
FROM orders
GROUP BY Customer
) maxOrder
ON maxOrder.Customer = orders.Customer
AND maxOrder.Max_Order_Amount = orders.Order_Amount
你会想加入同一张桌子......
SELECT Customer, order_date, amt
FROM orders o,
( SELECT Customer, MAX(Order_Amount) amt FROM orders GROUP BY Customer ) o2
WHERE o.customer = o2.customer
AND o.order_amount = o2.amt
;
除了自加入之外,您还可以执行以下操作:
SELECT o1.*
FROM orders o1 JOIN orders o2 ON o1.Customer = o2.Customer
GROUP BY o1.Customer, o1.Order_Amount
HAVING o1.Order_Amount = MAX(o2.Order_Amount);
有一篇很好的文章回顾了各种方法。
在 Oracle、db2、Sybase、SQL Server 2005+ 中,您将使用RANK() OVER
。
SELECT * FROM (
SELECT *
RANK() OVER (PARTITION BY Customer ORDER BY Order_Amount DESC) r
FROM orders) o
WHERE r = 1;
注意:如果Customer
有超过一个最大Order_Amount
的订单(即平局),使用RANK()
function 可以获得所有此类订单; 要仅获得第一个,请将RANK()
替换为ROW_NUMBER()
。
收集的另一种方法:
WITH tempquery AS
(
SELECT
Customer
,Order_Amount
,Order_Date
,row_number() OVER (PARTITION BY Customer ORDER BY Order_Amount DESC) AS rn
FROM
orders
)
SELECT
Customer
,Order_Amount
,Order_Date
FROM
tempquery
WHERE
rn = 1
如果您的数据库支持 CROSS APPLY 您也可以这样做,但它不能正确处理关系
SELECT [....]
FROM Customer c
CROSS APPLY
(SELECT TOP 1 [...]
FROM Orders o
WHERE c.customerID = o.CustomerID
ORDER BY o.Order_Amount DESC) o
查看此数据。SE 查询
with t as
(
select CUSTOMER,Order_Date ,Order_Amount,max(Order_Amount) over (partition
by Customer) as
max_amount from orders
)
select * from t where t.Order_Amount=max_amount
你可以尝试这样的事情:
SELECT Customer, MAX(Order_Amount), Order_Date
FROM orders O
WHERE ORDER_AMOUNT = (SELECT MAX(ORDER_AMOUNT) FROM orders WHERE CUSTOMER = O.CUSTOMER)
GROUP BY CUSTOMER, Order_Date
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.