views:

43

answers:

1

I'm trying to figure out how to query my database so that it will essentially first ORDER my results and then GROUP them... This question seems to be slightly common and I have found examples but I still don't quite grasp the 'how' to do this and use the examples in my own situation.... So all help is definitely appreciated.

Here are my MySQL tables:

books
book_id
book_title

users
user_id
user_name

book_reviews
review_id
book_id
user_id
review_date (unix timestamp date)

I would like to query 30 of the latest book reviews. They will simply display as:
Book Name
Username of Reviewer

However I would like to display each book no more than one time. So the review shown in the list should be the most recently added review. To do this I have been simply grouping by book_name and ordering by review_date DESC. But querying this way doesn't display the record with the most recently added review_date as the grouped by row so my data is incorrect.

Here is my current query:

SELECT books.books_title, users.user_name, book_reviews.review_id FROM books, users, book_reviews WHERE book_reviews.book_id = books.book_id AND book_reviews.user_id = users.user_id GROUP BY book_title ORDER BY review_date DESC LIMIT 30

From what I've read it seems like I have to have a subquery where I get the MAX(review_date) value but I still don't understand how to link it all up.

Thanks a ton.

+1  A: 

Use:

  SELECT x.book_title,
         x.user_name
    FROM (SELECT b.book_title,
                 u.user_name,
                 br.review_date,
                 CASE
                   WHEN @book = b.book_title THEN @rownum := @rownum + 1
                   ELSE @rownum := 1
                 END AS rank,
                 @book := b.book_title
            FROM BOOKS b
            JOIN BOOK_REVIEWS br ON br.book_id = b.book_id
            JOIN USERS u ON u.user_id = br.user_id
            JOIN (SELECT @rownum := 0, @book := '') r
        ORDER BY b.book_title, br.review_date DESC) x
   WHERE x.rank = 1
ORDER BY x.review_date DESC
   LIMIT 30

MySQL doesn't have analytical/ranking/windowing functionality, but this ranks the reviews where the latest is marked as 1. This is on a per book basis...

I exposed the review date to order by the latest of those which are the latest per book...

OMG Ponies
Thanks for the reply OMG Ponies! I'm still pretty inexperienced with MySQL and have never dabbled with user defined variables or CASE conditions before so I should be able to learn from this...That said I did get an error trying to run this: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@book := b.book_title FROM BOOKS b JOIN BOOK_REVIEWS b' at line 10
flight643
@flight643: Sorry - it was missing a comma after "AS rank". CASE expressions are almost identical to SWITCH statements, if you're familiar with them.
OMG Ponies