SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 31.05.2013 10:44:34

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Помогите составить запрос, котелок уже кипит :)

Есть такая таблица:
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, хотелось бы всё же использовать один запрос smile Памажите кто чем сможет))


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#2 31.05.2013 12:31:00

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Помогите составить запрос, котелок уже кипит :)


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#3 31.05.2013 13:23:55

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Помогите составить запрос, котелок уже кипит :)

Спасибо за ссылки, нашёл что нужно...
Стыдно признаться, но решение окзалось достаточно примитивным:
SELECT `ad_id`, max(`id`) FROM `legend` GROUP BY `ad_id`

Правда теперь думаю по скорости работы такого запроса при нескольких миллионах записей в таблице. Наверняка индекса на ad_id будет не достаточно и надо включить в этот индекс ещё и поле id?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#4 31.05.2013 14:00:41

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Помогите составить запрос, котелок уже кипит :)

Решение оказалось примитивным, потому-что получилось не полным smile
Мне ещё надо получить `banner_id` с найденным максимальным `id`. Я так понимаю надо ещё делать джоин на `legend` по `id`?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#5 31.05.2013 14:08:58

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Помогите составить запрос, котелок уже кипит :)

Добавил ещё один джоин и добился чего требовалось:
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`).


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#6 31.05.2013 21:54:18

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Помогите составить запрос, котелок уже кипит :)

Да, для подзапроса такой индекс оптимален.

P.S. Иногда ещё можно обойтись без джойна. См пример в FAQ №16. (к данному случаю это не относится, это так для расширения кругозора)

Неактивен

 

#7 31.05.2013 23:29:14

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Помогите составить запрос, котелок уже кипит :)

Пасиб, интересная статейка smile
Я и не знал, что в выборке обязательно должно присутствовать группирующее поле, хотя оно и логично получается, какой смысл группировать если само поле не селектить))) Кстати, вариант без джоина можно применить и в моём случае, используя какой-то разделитель при конкатенации и определяя его позицию, но я боюсь себе представить в какого дракона превратится такой запрос big_smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#8 31.05.2013 23:48:49

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Помогите составить запрос, котелок уже кипит :)

Группирующего поля в выборке может и не быть:
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`; -- неверный.

Неактивен

 

#9 01.06.2013 11:51:51

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Помогите составить запрос, котелок уже кипит :)

А, т.е. имеется ввиду, что в banner_id будет не ожидаемое значение, с чем я и столкнулся как раз smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson