2011-07-13 60 views
1

我一直在使用SQL幾年,這種類型的問題出現在這裏和那裏,我還沒有找到答案。但也許我一直在尋找錯誤的地方 - 我真的不知道該怎麼稱呼它。有關GROUP BY的SQL問題

爲簡潔起見,假設我有一個包含3列的表格:Customer,Order_Amount,Order_Date。每個客戶可能有多個訂單,每個訂單的數量和日期都有一行。

我的問題:是否有一種簡單的SQL方法來獲取每個客戶的最大訂單日期?

我可以做一些事情得到最大的訂單金額爲每一個客戶(和客戶提出的話),如:

SELECT Customer, MAX(Order_Amount) FROM orders GROUP BY Customer; 

但我也想獲得最大訂單的日期,這是我還沒有想出一個方法來輕鬆搞定。我原以爲這是一個數據庫常見的問題類型,因此在SQL中很容易實現,但我還沒有找到一個簡單的方法來完成它。一旦我將Order_Date添加到要選擇的列列表中,我需要將它添加到Group By子句中,我不認爲這會給我想要的。

+0

這取決於後端 –

+0

見(DBA.SE)http://dba.stackexchange.com/q/1002/630 – gbn

+0

如果客戶有相同數量的兩個命令應顯示? –

回答

2

除了自連接,你可以這樣做:

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); 

有一個很好的article審查的各種方法。

而在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()功能將讓你的所有命令;只能獲得第一個,請用ROW_NUMBER()替換RANK()

+1

RANK位於Oracle,db2,Sybase中。它的唯一SQL 2005及更高版本。 –

+0

@Conrad Frix感謝指正!更新的答案 – lxa

2

有沒有捷徑?最簡單的方法可能是加入一個子查詢:

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 
2

你將要參加同一個表...

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 
; 
0

你可以嘗試這樣的事:

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 
1

用於收集另一種方法:

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 
+0

正是我要發佈的,只是不能讓我的思想理順 – DForck42

+0

這不會工作,因爲你錯過了'GROUP BY'子句,並且你有'MAX(ORDER_DATE)'在那裏。你可能更好的只是刪除列。此外,ORDER BY應該是Order_Amount not Order_Date –

+0

感謝康拉德 - 誤解了這個問題,並引入了一個錯字。 – Martin

1

如果你的數據庫支持跨應用您可以做到這一點爲好,但它不處理領帶正確

SELECT [....] 
FROM Customer c 
CROSS APPLY 
(SELECT TOP 1 [...] 
FROM Orders o 
WHERE c.customerID = o.CustomerID 
ORDER BY o.Order_Amount DESC) o 

看到這個data.SE query