MySQL multiple ORDER BY conditions with limit for each condition

I have the entity Product (mapped to the table product) with the following fields:

  • createdAt (creation date)
  • numberOfLikes (number of received likes)
  • numberOfComments (number of received comments)

I need to create a paginated dashboard with 20 elements in each page (and no duplicates). Right now I am doing 3 different queries to extract and then combines the following items in a single list:

  • top 10 most recent products (ORDER BY createdAt DESC)
  • top 5 most liked products (ORDER BY numberOfLikes DESC) <== I am manually excluding the IDs from the first query with a WHERE id NOT IN
  • top 5 most commented products (ORDER BY numberOfComments DESC) <== I am manually excluding the IDs from the first and the second query with a WHERE id NOT IN

I would like to create a single query to extract all the 20 previous items. Is it possible?

I am using MySQL with Doctrine (Symfony) and I would be interested in a Doctrine-compatible solution.

Add Comment
2 Answer(s)

I don’t think it is possible to do it in a single query. I would use a combination of array methods, if the number of total posts is limited (like only 100 posts are visible in the dashboard).

Add Comment

This requires using UNION, which means you can’t have a Doctrine-compatible solution.

The core methodology would be the same as what you’re doing at the application level, except uglier. To get the exact same behavior, you would have to do something like

SELECT [text of first query] UNION SELECT [text of second query] WHERE `id` NOT IN (   SELECT `id` FROM (SELECT [text of first query]) ) UNION SELECT [text of third query] WHERE `id` NOT IN (   SELECT `id` FROM (SELECT [text of first query]) ) AND `id` NOT IN (   SELECT (SELECT `id` FROM [text of second query]) ) 

This means that the first query gets executed three times, independently, and the second query gets executed twice.

Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.