tags:

views:

42

answers:

1

Hello,

I'm developing an auctions application in which bids are held in a table with the following format:

id | user_id | auction_id | placed_at

I'd like to group the bids by user id and select their counts, but only if the user ids appear one after another. The bids are ordered by placed_at descending. Here's what I mean:

1 | 1 | 1 | 01-04-2010 00:00:06
2 | 1 | 1 | 01-04-2010 00:00:05
3 | 2 | 1 | 01-04-2010 00:00:04
4 | 2 | 1 | 01-04-2010 00:00:03
5 | 3 | 1 | 01-04-2010 00:00:02
6 | 2 | 1 | 01-04-2010 00:00:01

In this case, I should get:

count | user_id | auction_id
  2   |    1    |     1
  2   |    2    |     1
  1   |    3    |     1
  1   |    2    |     1

How can I achieve this result? The results will be used to generate an auction's activity stream, so they will be used to generate string such as 'John Smith bid on this auction 2 times.' The application is built with Ruby on Rails, if it helps.

Thank you in advance.

+1  A: 
SELECT  user_id, auction_id, COUNT(*)
FROM    (
        SELECT  @r := @r + CASE WHEN @user_id = user_id AND @auction_id = auction_id THEN 0 ELSE 1 END AS _g,
                user_id, auction_id,
                @user_id := user_id,
                @auction_id := auction_id
        FROM    (
                SELECT  @r := 0,
                        @user_id := NULL,
                        @auction_id := NULL
                ) vars,
                mytable
        ORDER BY
                auction_id DESC, placed_at DESC
        ) q
GROUP BY
        user_id, auction_id, _g
ORDER BY
        _g
Quassnoi
Wow. That's quite a query.
mjaz
@Quassnoi, I think this works for one auction, but if you add this row: (2, 1, 2, '01-04-2010 00:00:03'), it gives counts of (2,1,1,1,1) instead of (2,2,1,1) for auction 1. I think you need `ORDER BY auction_id, placed_at DESC`.
Mark Byers
Perfect... it works. Thank you!
mjaz
@Mark: if we should only group the bids from a single auction together, then yes, you're right. This was not initially clear enough for me, but now when I reread the question, I think that's exactly what the @op means.
Quassnoi