簡體   English   中英

SQL 關於 GROUP BY 的問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM