I have a photo gallery where I allow the user to create individual photo albums. I can display the name of each album like this.
$album = DB::getInstance()->query("SELECT `album_id`,`album_date`,`album_title` FROM `albums` ORDER BY `album_date` DESC");
What I'm trying to do is add a cover photo for each album, but can't seem to get my query correct. This is what I'm trying.
$album = DB::getInstance()->query("SELECT
albums.album_id,
albums.created,
albums.album_date,
albums.album_title,
gallery.file_name,
gallery.id,
gallery.album_id
FROM
albums
INNER JOIN gallery ON gallery.album_id = albums.album_id ORDER BY gallery.id DESC ;");
This is the result I get:
This is the result I'm trying to achieve:
I want each album name displayed with the last photo from each album as the cover photo.
If I add a LIMIT of 1 to my query, only one album is shown.
Here are my tables that are Joined together by a Foreign Key.
Albums Table:
Gallery Table:
Any solution to get this working would be much appreciated.
You can select the most recent image in each album using the following query:
SELECT album_id, MAX(id) id
FROM gallery
GROUP BY album_id
Alternatively, you can select a random image in each album like this:
SELECT g.album_id, (
SELECT id FROM gallery g2
WHERE g2.album_id = g.album_id
ORDER BY RAND()
LIMIT 1
) id
FROM gallery g
GROUP BY g.album_id
Either of the above queries could be plugged into a complete query:
SELECT a.album_id, a.created, a.album_date, a.album_title,
g.file_name, g.id, g.album_id
FROM albums a
INNER JOIN (
# above query goes here
) alb_img USING (album_id)
INNER JOIN gallery g ON g.id = alb_img.id
ORDER BY a.album_date DESC;
If you'd like to select empty albums as well as those containing one or more images change the INNER JOINs to LEFT JOINs.
Give this a try:
SELECT album_id, album_name, title, COALESCE(file_name, 'mydefaultimage.jpeg')
FROM albums
LEFT JOIN gallery on album_id = album
ORDER BY added DESC
LIMIT 1,1
if there's no image, title will be null
and filename will contain the default image name.
[EDIT] no ,
after the DESC
Try this:
SELECT
`album`.`album_title`
, (SELECT file_name FROM gallery WHERE gallery.`album_id` = album.`album_id` ORDER BY file_name DESC LIMIT 1) AS file_name
FROM
`album`
The first thing to do is to determine the latest id for the image for each album:
SELECT album_id, MAX(id) id FROM gallery GROUP BY album_id
You can easily put this as inline view (subquery) in a query
SELECT
a.album_name, g.file_name, g.title
FROM
(SELECT album_id, MAX(id) id FROM gallery GROUP BY album_id) a
JOIN
gallery g USING (album_id, id)
JOIN
albums a USING (album_id)
Solution:
SELECT albums.album_id,
albums.album_title,
albums.album_date,
albums.created,
gallery.id,
gallery.file_name
FROM `albums`
LEFT JOIN `gallery` ON (albums.album_id = gallery.album_id)
WHERE gallery.id IN
( SELECT MAX(gallery.id)
FROM `gallery`
GROUP BY gallery.album_id)
Explanation:
You first need to select the latest record corresponding to each album from gallery
table. Group the records with album_id
field, and user the aggregate function MAX()
to obtain the record with biggest id in the grouped result.
SELECT MAX(gallery.id)
FROM `gallery`
GROUP BY gallery.album_id
then join the gallery
table with albums
table with LEFT JOIN
and use the results of the above query in WHERE
clause. You can specify the whole set of fields you need to use in the SELECT
part of the outer query
SELECT albums.album_id,
albums.album_title,
albums.album_date,
albums.created,
gallery.id,
gallery.file_name
FROM `albums`
LEFT JOIN `gallery` ON (albums.album_id = gallery.album_id)
WHERE gallery.id IN
( FIRSTQUERY....)