Сортируем а затем групируем

Автор: Aport Суббота, Январь 31st, 2015 Нет комментариев

Рубрика: MySQL

Возникла необходимость найти ID строк, в которых у товара максимальный приоритет вывода. Казалось бы должен помочь запрос:

SELECT * FROM goods_img GROUP BY good_id ORDER BY sort DESC

Однако, этот запрос сначала группирует, а затем сортирует, а нам нужно наоборот.

Для начала схема таблицы:

CREATE TABLE goods_img (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT ‘ИД изображения’,
good_id int(10) UNSIGNED NOT NULL COMMENT ‘ID товара (goods.id)’,
sort int(11) NOT NULL COMMENT ‘Приоритетность изображения’,
PRIMARY KEY (id),
UNIQUE INDEX sort_good (good_id, sort)
)
ENGINE = MYISAM COMMENT = ‘Изображения товаров (у каждого товара может быть множество изображений)’;

Самое простой и нелепый вариант, который дает неправильное решение, такой:

SELECT * FROM goods_img AS t1
WHERE t1.sort = ( SELECT MAX( t1.sort ) FROM goods_img WHERE id = t1.id )
GROUP BY t1.good_id

Следующий вариант найденный в просторах интернета, уверяет, что сначала можно отсортировать, а затем сгрупировать:

SELECT * FROM
( SELECT * FROM goods_img ORDER BY sort DESC ) as my_table_tmp
GROUP BY good_id

Говорят, что GROUP BY берет данные первой строки, поэтому такой запрос сработал правильно, но мы не будем доверять тому, что говорят и напишем правильно:

SELECT t1.id, t1.good_id, t1.sort
FROM goods_img AS t1
LEFT JOIN goods_img AS t2 ON t2.good_id = t1.good_id AND t2.sort > t1.sort
WHERE t2.sort IS NULL

Этим запросом мы нашли строки товаров, у которых t2.sort будет равен NULL, потому что подумайте логически, ведь у каждого good_id будет такая sort больше которой быть не может, вот в этих строках и возникает NULL. Данный пример для сортировки DESC, а для сортировки ASC просто поменяйте знак больше на меньше.

Более подробно про GROUP BY: 1 - 2

p.s. DISTINCT vs GROUP BY

По сути это одно и тоже, но GROUP BY дает возможность использовать HAVING:

SELECT good_id FROM goods_img GROUP BY good_id HAVING COUNT(*) > 10

а вот дополнительно отфильтровать с помощью DISTINCT не выйдет, удачки!

 

Источник: yapro.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты