Nick
Nick

Reputation: 8309

Combining two queries into one with CakePHP

I'm working on a photo gallery project. I want to list the 20 most recently created albums and also show each of those albums' most recently uploaded photo (if it has one). The way I'm doing it now is querying the albums ($this->Album->find('all', ...)) and then passing the IDs from those results into my second query, which is the query that finds the most recently uploaded photo for the 20 albums found by the first query.

This is what the actual queries look like:

SELECT `Album`.`id`, `Album`.`name`, `Album`.`photo_count` FROM `mydb`.`albums` AS `Album` WHERE 1 = 1 ORDER BY `Album`.`created` DESC LIMIT 20

SELECT `Photo`.`album_id`, `Photo`.`name` FROM `mydb`.`photos` AS `Photo` WHERE `Photo`.`album_id` IN (21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2) GROUP BY `Photo`.`album_id` ORDER BY `Photo`.`created` DESC

I don't like doing two queries and that second query looks rather inefficient. Is there a way to make CakePHP do this in one, efficient query?

Upvotes: 0

Views: 995

Answers (1)

sgeddes
sgeddes

Reputation: 62831

I think you're looking for the following query which uses a subquery to return the most recent 20 albums, and then JOINs on the photos table to return the photos associated with those albums (replace with LEFT JOIN if needed):

SELECT A.Id, A.Name, A.Photo_Count, P.Name
FROM (SELECT * 
      FROM mydb.albums 
      ORDER BY Created DESC 
      LIMIT 20) A 
    INNER JOIN mydb.photos P ON A.Id = P.Album_Id
GROUP BY A.Id 
ORDER BY P.Created DESC

I removed your WHERE statement as I suspect those are the 20 Ids being returned from your Albums table.

EDIT: If I understood your comments correctly, you just need to add A.Created to your main query's ORDER BY clause:

SELECT A.Id, A.Name, A.Photo_Count, P.Name
FROM (SELECT * 
      FROM mydb.albums 
      ORDER BY Created DESC 
      LIMIT 20) A 
    INNER JOIN mydb.photos P ON A.Id = P.Album_Id
GROUP BY A.Id 
ORDER BY A.Created DESC, P.Created

Use ASC and DESC after each field as needed.

Upvotes: 2

Related Questions