Задавайте вопросы, мы ответим
Вы не зашли.
Есть такая таблица:
CREATE TABLE `legend` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ad_id` tinyint(3) unsigned NOT NULL COMMENT 'Ссылка на рекламный блок',
`banner_id` smallint(5) unsigned NOT NULL COMMENT 'Ссылка на баннер',
`added` datetime NOT NULL COMMENT 'Дата и время размещения',
`active` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'Доступность записи на главной странице',
PRIMARY KEY (`id`),
KEY `ad` (`ad_id`,`added`),
KEY `banner_id` (`banner_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Размещение баннеров';
В поле ad_id несколько уникальных значений. Нужно выбрать по одной записи для каждого значения ad_id, запись должна быть последней для этого ad_id, т.е. с максимальным id. Ума не хватило придумать правильную группировку с подзапросами, гоняю этот запрос в цикле для каждого ad_id, хотелось бы всё же использовать один запрос Памажите кто чем сможет))
Неактивен
Посмотрите
http://sqlinfo.ru/forum/viewtopic.php?id=1742 (до конца)
и
http://sqlinfo.ru/forum/viewtopic.php?id=5288
Неактивен
Спасибо за ссылки, нашёл что нужно...
Стыдно признаться, но решение окзалось достаточно примитивным:
SELECT `ad_id`, max(`id`) FROM `legend` GROUP BY `ad_id`
Правда теперь думаю по скорости работы такого запроса при нескольких миллионах записей в таблице. Наверняка индекса на ad_id будет не достаточно и надо включить в этот индекс ещё и поле id?
Неактивен
Решение оказалось примитивным, потому-что получилось не полным
Мне ещё надо получить `banner_id` с найденным максимальным `id`. Я так понимаю надо ещё делать джоин на `legend` по `id`?
Неактивен
Добавил ещё один джоин и добился чего требовалось:
SELECT `l`.`ad_id`, `b`.* FROM (SELECT `ad_id`, max(`id`) as `id` FROM `legend` GROUP BY `ad_id`) as `tmp`
JOIN `legend` AS `l` ON `l`.`id`=`tmp`.`id`
JOIN `banners` AS `b` ON `b`.`id`=`l`.`banner_id`
ORDER BY `tmp`.`ad_id`
Остался вопрос по индексу, подозреваю, что лучше всего будет INDEX(`ad_id`,`id`).
Неактивен
Да, для подзапроса такой индекс оптимален.
P.S. Иногда ещё можно обойтись без джойна. См пример в FAQ №16. (к данному случаю это не относится, это так для расширения кругозора)
Неактивен
Пасиб, интересная статейка
Я и не знал, что в выборке обязательно должно присутствовать группирующее поле, хотя оно и логично получается, какой смысл группировать если само поле не селектить))) Кстати, вариант без джоина можно применить и в моём случае, используя какой-то разделитель при конкатенации и определяя его позицию, но я боюсь себе представить в какого дракона превратится такой запрос
Неактивен
Группирующего поля в выборке может и не быть:
SELECT max(`id`) as `id` FROM `legend` GROUP BY `ad_id`; -- вполне корректный.
Не должно быть полей без группирующей функции и по которым не проводится группировка:
SELECT `ad_id`, max(`id`) as `id`, `banner_id` FROM `legend` GROUP BY `ad_id`; -- неверный.
Неактивен
А, т.е. имеется ввиду, что в banner_id будет не ожидаемое значение, с чем я и столкнулся как раз
Неактивен