Новости
Документация
Download
Webboard
Поиск
FAQ/ЧаВо
Обратная связь




MySQL.RU - Webboard



Вернуться
Проблема с GROUP и ORDER (Сергей) 28/07/2011 - 23:30:50
      Re: Проблема с GROUP и ORDER (Akina) 29/07/2011 - 12:57:52
      Re: Проблема с GROUP и ORDER (Сергей) 29/07/2011 - 15:36:21
      Re: Проблема с GROUP и ORDER (Akina) 30/07/2011 - 01:36:43
      Re: Проблема с GROUP и ORDER (Сергей) 30/07/2011 - 07:24:27

> Original message text:
> From: Сергей - 28/07/2011 - 23:30:50
> Subject:Проблема с GROUP и ORDER
> -----------------
> Требуется сделать выборку из таблицы товаров:
> Сотня самых тяжелых позиций Price * in_stock
> Товары могут дублироваться и при этом иметь разные названия title и одинаковые keywords при совпадении keywords нужен только тот у которого максимальный вес
> Делал так:
> SELECT *
> FROM (
> SELECT `id`,
> `title`,
> `keywords`,
> (`Price` * `in_stock`) AS `w`
> FROM `products`
> ) AS `t`
> GROUP BY `keywords`
> ORDER BY `w` DESC
> LIMIT 100
>
> Независимо от наличия/отсутствия/режима сортировки GROUP оставляет только первую в порядке добавления в таблицу запись.
> Вопрос как обмануть GROUP?
>


From: Akina - 30/07/2011 - 01:36:43
Subject:Проблема с GROUP и ORDER
-----------------
Посмотрите, что на самом деле делает Ваш запрос:

1. Подселект делает выборку нужных полей плюс формирует поле необходимое для последующей сортировки. Одна мелочь - он ни разу не агрегатный.
2. Выполняется группировка по указанному полю - так что агрегатным является внешний запрос. Поскольку в списке полей залеплена звёздочка, то для каждой группы берётся одна СЛУЧАЙНАЯ запись. Это, кстати, явно документировано.
3. Ну и потом уже сортировка и лимит.

Иными словами, логика далека от желаемой. Давайте всё-таки построим (хоть какой-то) запрос в соответствии с логикой.

Этап 1. Выберем нужные поля и проведём необходимые расчёты.

(
SELECT `p1`.`id`, `p1`.`title`, `p1`.`keywords`, (`p1`.`Price` * `p1`.`in_stock`) AS `w`
FROM `products` `p1`
) AS `subq_1`

Этап 2. Сгруппируем по нужному полю, с выбором максимального значения рассчитанной записи.

(
SELECT `s1`.`keywords`, MAX(`s1`.`w`) AS `max_w`
FROM `subq_1` `s1`
GROUP BY `s1`.`keywords`
) AS `subq_2`

Этап 3. Получим остальные поля для отобранных записей. C сортировкой и лимитом.

SELECT `s2`.*
FROM `subq_1` `s2`
INNER JOIN `subq_2` `s3`
ON `s2`.`keywords`=`s3`.`keywords`
AND `s2`.`w`=`s3`.`max_w`
ORDER BY `s2`.`w` DESC
LIMIT 100

Этап 4. Выполним подстановки, попутно устраняя неоднозначности корректировкой алиасов, и получим окончательный текст запроса.

SELECT `s2`.*
FROM
(
SELECT `p1`.`id`, `p1`.`title`, `p1`.`keywords`, (`p1`.`Price` * `p1`.`in_stock`) AS `w`
FROM `products` `p1`
) `s2`
INNER JOIN
(
SELECT `s1`.`keywords`, MAX(`s1`.`w`) AS `max_w`
FROM
(
SELECT `p11`.`id`, `p11`.`title`, `p11`.`keywords`, (`p11`.`Price` * `p11`.`in_stock`) AS `w`
FROM `products` `p11`
) `s1`
GROUP BY `s1`.`keywords`
) `s3`
ON `s2`.`keywords`=`s3`.`keywords`
AND `s2`.`w`=`s3`.`max_w`
ORDER BY `s2`.`w` DESC
LIMIT 100

Оптимально? нет... но работать обязан. Опять же проблемы, если в какой-то группе на этапе 3 окажется несколько записей с разными keywords, соответствующих максимальному значению - за Ваш счёт.

Хотите оптимальнее - читайте материал по ссылке ещё (сколько потребуется) раз.


[Это сообщение - спам!]

Последние сообщения из форума

Уважаемые посетители форума MySQL.RU!
Убедительная просьба, прежде чем задавать свой вопрос в этом форуме, обратите внимание на разделы:
- ответы на наиболее часто задаваемые вопросы - FAQ
- раздел документация
- раздел поиск по сообщениям форума и документации
Также, старайтесь наиболее подробно указывать свою ситуацию (версию операционной системы, версию MySQL, версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
 Имя:
 E-mail:
 Тема:
 Текст:
Код подтверждения отправки: Code
39314



РЕКЛАМА НА САЙТЕ
  Создание сайтов | |