Say you wanted a paginated list of articles (25 per page), but you also wanted to get their images (with some conditions), and each article might have multiple images. Using the basic LIMIT would return eg the first 25 ROWS, but not the first 25 articles:
SELECT article.id,
article.name,
image.id,
image.file
FROM article
JOIN image ON article.id = image.article_id
WHERE article.status = 1
AND image.status=1 LIMIT 25
So I started running the limit on a subquery:
SELECT article.id,
article.name,
image.id,
image.file
FROM
(SELECT article.id,
article.name
FROM article
WHERE article.status = 1 LIMIT 25) AS article
JOIN image ON article.id = image.article_id
WHERE image.status = 1
However, the presence of a given article in the results also depends on it having an image with status=1, so it’s possible to have a page of less than 25 articles, although the are more articles on the next page.
The only way I can think of to solve this in sql is to run the entire query in a subquery with a GROUP AND a limit, and then re-do the join on image:
SELECT article.id,
article.name,
image.id,
image.file
FROM
(SELECT article.id,
article.name
FROM article
JOIN image ON article.id = image.article_id
WHERE article.status = 1
AND image.status=1
GROUP BY article.id LIMIT 25) AS article
JOIN image ON article.id = image.article_id
WHERE image.status=1
This gives me the first 25 articles, and the correct images. It might be more than 25 rows in all, but it’s 25 articles.
Another approach would be to just return all the rows and iterate in the application. I’m not a fan of that approach.
Any more elegant solutions I’ve missed? I’m using MariaDB and PHP.