Да, это, вероятно, еще один наибольший n-на-группу вопрос ... Но я попробовал по крайней мере дюжину ответов на вопросы, уже размещенные здесь, и не смог найти тот, которыйработает для того, что я пытаюсь сделать.Возможно, это что-то очень простое, что я упускаю из виду, или то, что я хочу, немного другое.Вероятно, первое: /
У меня есть две таблицы (InnoDB), одна для наборов изображений, которая имеет одну строку на набор с некоторой информацией, такой как set_title, с каким продуктом она связана, на /автономный статус и дата добавлены:
GallerySets
- set_id (основной)
- product_id (внешний ключ)
- set_title (varchar 128)
- set_status (перечисление онлайн / офлайн, индекс)
- set_dateadded (datetime, index)
И таблица для отдельных изображений, каждый набор имеетодно или несколько изображений.Хотя поля пути нет, я просто использую его вроде set_id / pic_id.jpg ... Есть и другие поля, такие как viewcounts и т. Д., Но они не нужны для этой проблемы, поэтому я их пропустил.
GalleryPics
- pic_id (основной)
- set_id (основной, внешний ключ)
- pic_dateadded (datetime, index)
В основном я хочу показать 2 изображения для последних 4 комплектов.У меня есть этот запрос ниже, который приближается к тому, что я хочу, единственное, что он не делает, это ограничивает его до 2 на набор:
SELECT s.`set_id`, s.`set_title`, s.`set_dateadded`, p.`pic_id`, p.`pic_dateadded`
FROM `GallerySets` s
LEFT JOIN `GalleryPics` p
ON (s.`set_id` = p.`set_id`)
WHERE s.set_status = 'online'
ORDER BY s.`set_dateadded` DESC, p.`pic_dateadded` ASC
Он просто показывает все, конечно.В других вопросах (например, этот ) я видел, как меняли ON-line и добавляли HAVING, чтобы добиться цели:
ON (s.`set_id` = p.`set_id` AND s.`set_dateadded` < p.`pic_dateadded`)
HAVING COUNT(*) < 3
Я пробовал всевозможные варианты этогос HAVING, но это не приближает меня.На самом деле он возвращает либо ноль результатов, либо одну строку на каждый набор, как только я добавлю в него какую-либо строку HAVING.Возможно, я пытаюсь использовать неправильное решение "наибольшие числа групп"?Может быть, потому что я хочу отсортировать по полю даты и времени, а не по идентификаторам с автоинкрементом?
Требуемые результаты
На самом деле хочу больше походить на первые три изображения из последних пяти наборов,но для того, чтобы привести не слишком длинный пример результата ... немного его настроить.
set_id | set_title | set_dateadded | pic_id | pic_dateadded
4 | blah4 | 2011-10-04 00:00:00 | 32 | 2011-10-04 12:44:01
4 | blah4 | 2011-10-04 00:00:00 | 33 | 2011-10-04 12:44:02
3 | blah3 | 2011-10-03 00:00:00 | 26 | 2011-10-03 12:33:01
3 | blah3 | 2011-10-03 00:00:00 | 27 | 2011-10-03 12:33:02
2 | blah2 | 2011-10-02 00:00:00 | 11 | 2011-10-02 12:22:01
2 | blah2 | 2011-10-02 00:00:00 | 12 | 2011-10-02 12:22:02
1 | blah1 | 2011-10-01 00:00:00 | 1 | 2011-10-01 12:11:01
1 | blah1 | 2011-10-01 00:00:00 | 2 | 2011-10-01 12:11:02
Начинаю думать, что это может быть не самая плохая идея, если один запрос получит последние наборы, а затемиспользуйте цикл while в php с запросом, чтобы получить несколько картинок за комплект.: /
Решение
Рабочее решение найдено благодаря Джорджу Псаракису.Здесь показаны первые два изображения в последних четырех наборах:
SET @rownum=0;
SET @last_group_id=0;
SELECT gp.pic_id, gp.pic_dateadded, gs.*,
@rownum:=IF(gp.set_id<>@last_group_id,1,@rownum+1) AS rn, @last_group_id:=gp.set_id
FROM GalleryPics gp JOIN
(
SELECT * FROM GallerySets WHERE set_status='online'
ORDER BY gs.set_dateadded DESC LIMIT 5
) AS gs
ON gs.set_id = gp.set_id
HAVING rn < 4
ORDER BY gs.set_dateadded DESC, gp.pic_dateadded ASC
(время запроса составляет около 0,0030 с для 900+ наборов и 10000+ изображений)