MySQl GROUP BY и ORDER BY не делают то, что я хочу - PullRequest
4 голосов
/ 12 августа 2010

Я хочу отсортировать результаты, прежде чем сгруппировать их, но, похоже, я не могу это сделать.

У меня есть этот запрос:

SELECT DISTINCT
 product.id,
 product_number_value.att_value AS product_number,
 color_number_value.option_code AS color_number,
 size_value.option_code AS size_code,
 size_value.option_position AS size_position
FROM
 product
INNER JOIN product_attribute_relational AS product_number_relational ON product_number_relational.product_id = product.id
INNER JOIN product_att_varchar AS product_number_value ON product_number_relational.product_att_id = product_number_value.product_att_id
INNER JOIN product_attribute_relational AS color_number_relational ON color_number_relational.product_id = product.id
INNER JOIN product_att_select AS color_number_select ON color_number_relational.product_att_id = color_number_select.product_att_id
INNER JOIN attribute_option_value AS color_number_value ON color_number_select.att_value = color_number_value.option_id
INNER JOIN product_attribute_relational AS size_relational ON product.id = size_relational.product_id
INNER JOIN product_att_select AS size_select ON size_relational.product_att_id = size_select.product_att_id
INNER JOIN attribute_option_value AS size_value ON size_select.att_value = size_value.option_id
WHERE
 product_number_relational.att_id = 1 AND
 color_number_relational.att_id = 2 AND
 size_relational.att_id = 3 AND
 product.id IN (365, 366, 367, 368, 369, 371, 372, 373, 374)
ORDER BY
 product.id ASC

Результат - следующая таблица:

id  product_number  color_number  size_code  size_position
365 F23740   311    S   24
366 F23740   311    M   25
367 F23740   311    L   26
368 F23740   311    XL   27
369 F23740   311    XS   23
371 F23745   213    S   24
372 F23745   213    M   25
373 F23745   213    L   26
374 F23745   213    XL   27

Если я сгруппирую по номеру product_number, color_number, я получу идентификатор 365 и 371.
Но я хочу получить идентификатор 369 и 371, потому чтоЯ хочу, чтобы результаты сначала упорядочивались по size_position, прежде чем сгруппировать их.

Я действительно понятия не имею, как это сделать?! ??

Может кто-нибудь помочь мне, пожалуйста ??

Спасибо!

Ответы [ 3 ]

2 голосов
/ 12 августа 2010

Это проблема использования несгруппированных столбцов в сгруппированном запросе.Как правило, этого следует избегать.Некоторые механизмы БД мешают вам делать это, потому что это не имеет логического смысла - если я хочу product.id для группы, но какой механизм БД выбрать, потому что для одной группы есть несколько вариантов?

ORDER BY предназначен только для работы с агрегатами или сгруппированными столбцами при использовании GROUP BY, но я не уверен, что вы можете легко агрегировать.Вы ищете product.id для строки с MIN (size_position) в группе.Я думаю, что подзапрос для выделения этой строки для каждой группы может быть единственным способом;Я не могу придумать простой способ, чтобы вытащить это из головы.

РЕДАКТИРОВАТЬ

Мой инстинкт в этих случаях всегда заключается в том, чтобы делать это вдва шага.Мне не нравятся гигантские неповоротливые запросы с вложенными подзапросами, просто потому, что я нахожу их нечитаемыми.У вас очень длинный запрос по нормализованной схеме, поэтому я не буду пытаться разбить запрос здесь, скорее всего, сделаю ошибку.

Запрос 1 вызовет product_number, color_number и MIN(size_position) (группировка по product_number, color_number) во временную таблицу.

Запрос 2 затем извлекает product_id для каждого product_number, color_number, size_position в временной таблице.Таким образом, вы можете выполнить соединение непосредственно с позицией минимального размера.

Отрицательная производительность использования временных таблиц во многих случаях преувеличена (не во всех, но, конечно, для 99% запросов, которые я выполнял впоследние 10 лет в торговых приложениях).

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

1 голос
/ 12 августа 2010

Если вы группируете по product_number, color_number, значения, возвращаемые для идентификатора столбца, являются неопределенными (поскольку они не одинаковы для каждой пары product_number, color_number). См. здесь для подробного объяснения.

Итак, вы говорите: «Я хочу отсортировать свои результаты, прежде чем сгруппировать их», можете ли вы сказать, почему вы хотите сгруппировать их? Именно то, что вы хотите получить от него.

РЕДАКТИРОВАТЬ: после комментария:

SELECT DISTINCT

 product_number_value.att_value AS product_number,
 color_number_value.option_code AS color_number,
 min(size_value.option_position) AS sizePosition
from ...

group by product_number, color_number order by sizePosition

У вас будет номер продукта, но не идентификатор.

0 голосов
/ 12 августа 2010

Попробуйте упорядочить по обоим столбцам:

... ORDER BY product.id, size_position ASC

Сначала будет отсортирована по id, а затем по размеру_позиции.

...