2010-08-28 231 views
7

我有一張名爲order的表,其中包含列id,user_id,priceitem_id。項目價格不固定,我想選擇每個項目的最昂貴的訂單。我想在同一個查詢中選擇user_id,item_idprice。我嘗試了以下查詢,但它不返回正確的結果集。選擇多個最大值

SELECT user_id, item_id, MAX(price) 
FROM order 
GROUP BY item_id 

此查詢返回的某些行有錯誤user_id。但是,結果集中的所有行都會顯示每個項目的正確最高價格。通過item_id

回答

9

您可能需要使用派生表,如下所示:

SELECT o1.item_id, o1.max_price, o2.user_id user_of_max_price 
FROM  (
      SELECT item_id, MAX(price) max_price 
      FROM `order` 
      GROUP BY item_id 
     ) o1 
JOIN  `order` o2 ON (o2.price = o1.max_price AND o2.item_id = o1.item_id) 
GROUP BY o1.item_id; 

測試用例:

CREATE TABLE `order` (user_id int, item_id int, price decimal(5,2)); 

INSERT INTO `order` VALUES (1, 1, 10); 
INSERT INTO `order` VALUES (1, 2, 15); 
INSERT INTO `order` VALUES (1, 3, 8); 
INSERT INTO `order` VALUES (2, 1, 20); 
INSERT INTO `order` VALUES (2, 2, 6); 
INSERT INTO `order` VALUES (2, 3, 15); 
INSERT INTO `order` VALUES (3, 1, 18); 
INSERT INTO `order` VALUES (3, 2, 13); 
INSERT INTO `order` VALUES (3, 3, 10); 

結果:

+---------+-----------+-------------------+ 
| item_id | max_price | user_of_max_price | 
+---------+-----------+-------------------+ 
|  1 |  20.00 |     2 | 
|  2 |  15.00 |     1 | 
|  3 |  15.00 |     2 | 
+---------+-----------+-------------------+ 
3 rows in set (0.00 sec) 
+0

它工作完美。謝謝,丹尼爾! – Ohas 2010-08-28 11:53:15

1

您查詢組行。如果你有item_id 1多個項目,具有不同user_id,只會挑頭user_id,而不是user_id具有最高的性價比。

+0

是的,沒錯。那麼,我該如何實現我在這裏要做的?我試圖找出誰以最大的價格買了這件物品,以及那個價格是多少。 – Ohas 2010-08-28 11:22:21

0

你要麼需要按ITEM_ID和USER_ID(顯示每用戶項目最大的價格),或者如果你想組在短短的項目,你需要重新考慮user_id列。 例如顯示價格最大一個項目,並顯示誰做對價格變化的最後一個用戶,或顯示最高價格的項目,並顯示誰提出的最高報價爲項目等用戶看一看this post對於某一些模式爲了做到這一點。

+0

我無法獲得該商品,其最高價格以及在一個查詢中提供該價格的用戶嗎? – Ohas 2010-08-28 11:23:29

2

您需要先獲取每個商品ID的最高價格,然後返回order才能獲得該商品按最高價格訂購的記錄。像下面的查詢應該工作。儘管如此,它會以最高的物品價格返回所有記錄。

SELECT user_id, item_id, price 
FROM order o 
JOIN (
     SELECT item_id, max(price) max_price 
     FROM order 
     GROUP BY item_id 
    ) o2 
    ON o.item_id = o2.item_id AND o.price = o2.max_price; 
2

這以每個組最大的問題。這個常見問題有various approaches。在MySQL上,使用空自連接通常比涉及子查詢的任何操作更快更簡單:

SELECT o0.user_id, o0.item_id, o0.price 
FROM order AS o0 
LEFT JOIN order AS o1 ON o1.item_id=o0.item_id AND o1.price>o0.price 
WHERE o1.user_id IS NULL 

即。 「選擇每行存在價格較高的相同商品不存在其他行」。

(如果兩行有,你會得到兩個返回相同的最高價格。究竟如何才能在平局的情況下,這樣做是爲每個組最大的解決方案的一個普遍問題。)

+1

[您提供的鏈接](http://kristiannielsen.livejournal.com/6745.html)中的基準沒有顯示派生表(不相關的子查詢)方法比null-self-join快得多? ...我也曾經認爲MySQL中的null-self-join稍快,事實上,我對這些基準感到非常驚訝。我有一種感覺,我會自己做一些測試:) ......無論如何012 + 1 + 1 + – 2010-08-28 13:41:40

+1

是的,結果當然會根據涉及的表和索引的大小而變化。我通常發現,在過去使用MySQL(其子查詢支持已知相對年輕,因此可能沒有儘可能優化),我的特定數據集上的null-self-join速度最快。使用最新版本的MySQL進行調查會更有趣。 – bobince 2010-08-28 14:43:01

1
SELECT user_id, item_id, MAX(price) 
FROM order 
GROUP BY item_id 

的您使用的SQL與GROUP矛盾。 一旦你使用GROUP,MySQL將始終選擇第一個USER_ID,但最高價,爲什麼用戶是錯誤的,但價格是正確的就是這個道理。

你可以嘗試添加ORDER BY price DESC看看發生什麼,但我沒有在我的環境試試。

3

也許這是長一點,但你在可讀性

SELECT 
     * 
FROM 
    `order` 
JOIN 
    (
     SELECT 
      item_id, 
      MAX(price) price 
     FROM 
      `order` 
     GROUP BY 
      item_id 
    ) 
    USING(item_id, price); 
0

獲得,如果你想頂部2從爲了試試這個...

如果你想前3名則只需改變最後一個條件 哪裏item_rank in (1,2) ;where item_rank in (1,2,3) ;

select * from 
    (select item_id , price 
    , @curRow % @curNval as item_rank 
    , @curRow := @curRow + 1 AS row_number 
    from `order` , (SELECT @curRow := 1 , @curNval := 3) r 
    order by item_id , price desc ) tab where item_rank in (1,2) ; 
+0

可以用作item_rank> 2或item_rank> n – Kapil 2012-12-21 07:31:49