Jump to content

Using two COUNTs in a query - a more elegant solution


Recommended Posts

Hello,

 

I have two tables in my database, a table of books, 'bookinfo' with book_ids and a table of reviews, 'reviews' with review_ids.

 

Each row in the review table references a particular book in the book table by book_id. There is also a 'boolean' enum ('Y', 'N') that specifies if a review is official or not.

 

I want to perform a single query that returns one row for every book in the book table, and counts both the total reviews and the official reviews.

 

So far I have achieved this as follows:

 

SELECT book_title,

  SUM(CASE WHEN bookinfo.book_id = reviews.book_id AND reviews.official="Y" THEN 1 ELSE 0 END) AS num_official_reviews,

  SUM(CASE WHEN bookinfo.book_id = reviews.book_id THEN 1 ELSE 0 END) AS num_reviews

FROM bookinfo, reviews

GROUP BY bookinfo.game_id

 

So this works, but doesn't seem very elegant to me.

 

I can achieve the results in two queries using a JOIN which is slightly nicer:

 

SELECT book_title,

  COUNT(reviews.review_id) AS num_public_reviews

FROM bookinfo LEFT JOIN reviews ON bookinfo.book_id = reviews.book_id AND reviews.official="Y"

GROUP BY bookinfo.book_id

 

and

 

SELECT book_title,

  COUNT(reviews.review_id) AS num_reviews

FROM bookinfo LEFT JOIN reviews ON bookinfo.book_id = reviews.book_id

GROUP BY bookinfo.book_id

 

So I was wondering if there is a better way to do this, perhaps using the above JOIN construct in a single query? Is that possible?

 

Many thanks,

 

What about this?

SELECT book_title,
  SUM(CASE WHEN bookinfo.book_id = reviews.book_id AND reviews.official="Y" THEN 1 ELSE 0 END) AS num_official_reviews, COUNT(*) AS num_reviews
FROM bookinfo
LEFT JOIN reviews ON bookinfo.book_id = reviews.book_id
GROUP BY bookinfo.game_id

 

I have not tested the query.

As you are joining on the condition "bookinfo.book_id = reviews.book_id" then inclusion in the CASE is superfluous

 

SELECT book_title,
  SUM(CASE WHEN reviews.official="Y" THEN 1 ELSE 0 END) AS num_official_reviews, 
  COUNT(*) AS num_reviews
FROM bookinfo
LEFT JOIN reviews ON bookinfo.book_id = reviews.book_id
GROUP BY bookinfo.game_id

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.