tags:

views:

98

answers:

2

I need some help formulating this query. I have two (relevant) tables, which I will dump here for reference:

CREATE TABLE IF NOT EXISTS `albums` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT 'owns all photos in album',
  `parent_id` int(11) DEFAULT NULL,
  `left_val` int(11) NOT NULL,
  `right_val` int(11) NOT NULL,
  `name` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
  `num_photos` int(11) NOT NULL,
  `date_created` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `parent_id` (`parent_id`,`name`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

CREATE TABLE IF NOT EXISTS `photos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `album_id` int(11) NOT NULL,
  `filename` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `num_views` int(11) NOT NULL DEFAULT '0',
  `date_uploaded` int(11) NOT NULL,
  `visibility` enum('friends','selected','private') COLLATE utf8_unicode_ci NOT NULL,
  `position` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=26 ;

Now I want to grab the first photo (lowest position #) from each album owned by a certain user.

Here's what I'm trying:

SELECT * FROM albums JOIN photos ON photos.album_id=albums.id WHERE albums.user_id=%s GROUP BY album_id HAVING min(position)

But the having clause doesn't seem to have an effect. What's the problem?

A: 

You could use ORDER BY and LIMIT your results to the first row like so:

SELECT photos.* 
FROM 
  albums, photos
WHERE
  photos.album_id=albums.id
  AND albums.user_id=%s
ORDER BY
  photos.position ASC
LIMIT 1
cgmack
Each user can own more than one album...
tekBlues
Ahh. Missed that detail in the question. Your sub query approach works.
cgmack
+1  A: 
select * from album, photos 
where album_id=albums.id  
and albums.user_id='user_id'
and photos.id = (select id from photos where 
album_id = album.id order by position LIMIT 1)
tekBlues
This looks like it's working. Is it really necessary to use a subquery? Sounds so simple in my head, but I guess not in SQL.
Mark
I think it's necessary
tekBlues
Actually, I think there's one more caveat. This assumes 'position' is unique... which it should be, but is there anyway we can make this more robust so that it doesn't return more than one photo per album if the min(position) is NOT unique? I'm in development and the positiong system isn't quite set up :p
Mark
Ok, now I'm joining by id and ordering by position in the subquery and taking just the first row, that must do it...
tekBlues
Yup. That does the trick. Thank you so much! But just so I understand, that subquery is executed once for each album owned by user X or what?
Mark
Don't think "times" that's procedural. Think in terms of sets, the sub query gets the set of all the photos of **each album**, sorts by position and takes the first row.
tekBlues