2010-08-28 149 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