2014-01-21 68 views
2

我有一个SQL表包含销售某些项目的数据。事实上,它有销售物品的日志。MySQL:按多列分组时选择第一行或最后一行

例如,有一个销售包含2项:键盘(id:1)和鼠标(id:2)。买家可以对每件商品进行出价并多次出价,例如eBay。所以我们假设有两个买家(ids are 97 and 98)几次出价。相关的数据是:

bid_id | buyer_id | item_id | amount  | time    | 
1  | 97   | 1  | 44.26  | 2014-01-20 15:53:16 | 
2  | 98   | 2  | 30.47  | 2014-01-20 15:54:52 | 
3  | 97   | 2  | 40.05  | 2014-01-20 15:57:47 | 
4  | 97   | 1  | 42.46  | 2014-01-20 15:58:36 | 
5  | 97   | 1  | 39.99  | 2014-01-20 16:01:13 | 
6  | 97   | 2  | 24.68  | 2014-01-20 16:05:35 | 
7  | 98   | 2  | 28   | 2014-01-20 16:08:42 | 
8  | 98   | 2  | 26.75  | 2014-01-20 16:13:23 | 

在这个表,我需要的第一个项目,提供每个用户和最后报价为每一位用户选择的数据。

所以,如果我选择第一项提供了每一个用户(不同的),返回的数据应该是这样的:

bid_id | buyer_id | item_id | amount  | time    | 
1  | 97   | 1  | 44.26  | 2014-01-20 15:53:16 | 
2  | 98   | 2  | 30.47  | 2014-01-20 15:54:52 | 
3  | 97   | 2  | 40.05  | 2014-01-20 15:57:47 | 

如果我选择为每个用户最后的报价,回报应该是这样的:

bid_id | buyer_id | item_id | amount  | time    | 
5  | 97   | 1  | 39.99  | 2014-01-20 16:01:13 | 
6  | 97   | 2  | 24.68  | 2014-01-20 16:05:35 | 
8  | 98   | 2  | 26.75  | 2014-01-20 16:13:23 | 

因为我必须把每个项目的每个用户,我试图GROUP BY两个buyer_iditem_id,然后SELECTtimebid_idMIN值。但它总是返回我第一个bid_id但最新amount行(实际上是最后提供)。

这是我试过的查询:

SELECT MIN(`bid_id`) AS `bid_id`,`buyer_id`,`item_id`,`amount`,`time` FROM `offers` GROUP BY `buyer_id`,`item_id` 

,结果是:

bid_id | buyer_id | item_id | amount  | time    | 
1  | 97   | 1  | 39.99  | 2014-01-20 16:01:13 | 
2  | 97   | 2  | 24.68  | 2014-01-20 16:05:35 | 
3  | 98   | 2  | 26.75  | 2014-01-20 16:13:23 | 

正如你所看到的,它按和ID是正确的,但该行其余值是不。

分组购买多列时,如何正确SELECT第一行和/或最后一行?

回答

1
SELECT o.`bid_id`,o.`buyer_id`,o.`item_id`,o.`amount`,o.`time` FROM `offers` o 
JOIN 
(SELECT MIN(`bid_id`) AS `bid_id`,`buyer_id`,`item_id`,`amount`,`time` FROM `offers` GROUP BY `buyer_id`,`item_id`)x 
ON x.bid_id=o.bid_id AND x.buyer_id=o.buyer_id 
0

第一提供SQL:

SELECT 
* 
FROM 
    offers AS o1 
WHERE 
NOT EXISTS (
    SELECT 
     1 
    FROM 
     offers o2 
    WHERE 
     o1.buyer_id = o2.buyer_id 
    AND o1.item_id = o2.item_id 
    AND datetime(o1.time) > datetime(o2.time) 
) 

最后提供SQL:只需更改为datetime(o1.time)<日期时间(o2.time)(我使用SQLite〜)

0

这里的另一个取,使用Quassnoi's ranking trick here

对于第一出价:

SELECT x.bid_id, x.buyer_id, x.item_id, x.amount, x.time 
FROM 
(
    SELECT o.bid_id, o.buyer_id, o.item_id, o.amount, o.time, 
    @combo :=CASE WHEN NOT(@curItem = o.item_id AND @curBuyer = o.buyer_id) 
        THEN 1 ELSE @combo+1 END AS Rank, 
    @curItem:=o.item_id AS item, 
    @curBuyer:=o.buyer_id AS buyer 
    FROM 
    (
    SELECT o.bid_id, o.buyer_id, o.item_id, o.amount, o.time 
     FROM offers o 
     ORDER BY o.buyer_id, o.item_id, o.bid_id 
) o, 
    (SELECT @curItem := -1) itm, 
    (SELECT @curBuyer:= -1) buy 
) x 
WHERE x.Rank = 1; 

在过去的投标查询,你只需要改变ORDER BYo.buyer_id, o.item_id, o.bid_id DESC

SqlFiddle here

-1

请尝试以下查询所需的输出。 SQL FIDDLE LINK:http://sqlfiddle.com/#!2/916c2/15

(select f.bid_id,f.buyer_id,f.item_id,f.amount,f.time from offers f join 
    (select buyer_id,item_id,min(time) as time from offers 
    group by buyer_id,item_id)t 
    on f.buyer_id=t.buyer_id and f.item_id=t.item_id 
    and f.time=t.time) 
    union 
    (select f.bid_id,f.buyer_id,f.item_id,f.amount,f.time from offers f join 
    (select buyer_id,item_id,max(time) as time from offers 
    group by buyer_id,item_id)t 
    on f.buyer_id=t.buyer_id and f.item_id=t.item_id 
    and f.time=t.time);