группа mysql, не делая того, что я ожидаю?

#mysql #group-by

#mysql #группировать по

Вопрос:

 SELECT
      bp.product_id,bs.step_number,
      p.price, pd.name as product_name
    FROM 
      builder_product bp
      JOIN builder_step bs ON bp.builder_step_id = bs.builder_step_id
      JOIN builder b ON bp.builder_id = b.builder_id
      JOIN product p ON p.product_id = bp.product_id
      JOIN product_description pd ON p.product_id = pd.product_id
      WHERE b.builder_id = '74' and bs.optional != '1'
    group by bs.step_number
    ORDER by bs.step_number, p.price
  

но вот мои результаты

 88  1   575.0000    Lenovo Thinkcentre POS PC
244 2   559.0000    Touchscreen with MSR - Firebox 15amp;quot;
104 3   285.0000    Remote Order Printer - Epson
97  4   395.0000    Aldelo Lite
121 5   549.0000    Cash Register Express  - Pro
191 6   349.0000    Integrated Payment Processing
155 7   369.0000    Accessory - Posiflex 12.1amp;quot; LCD Customer Display
  

Ответ №1:

Предполагается, что GROUP BY работает не так. Если вы группируете по нескольким столбцам, ваш select может возвращать только:

  • Столбцы, которые вы группируете по
  • Функции агрегирования из других столбцов, таких как MIN (), MAX (), AVG ()…

Итак, вам нужно будет сделать это:

 SELECT
  bs.step_number,
  MIN(p.price) AS min_price, pd.name as product_name
FROM 
  builder_product bp
  JOIN builder_step bs ON bp.builder_step_id = bs.builder_step_id
  JOIN builder b ON bp.builder_id = b.builder_id
  JOIN product p ON p.product_id = bp.product_id
  JOIN product_description pd ON p.product_id = pd.product_id
  WHERE b.builder_id = '74' and bs.optional != '1'
group by bs.step_number, pd.name
ORDER by bs.step_number, min_price
  

(MySQL допускает очень упрощенный синтаксис и с радостью удалит случайные строки для каждой группы, но другие СУБД вызовут ошибку с вашим исходным запросом.)

Комментарии:

1. мне также нужен product_id для каждой из минимальных цен

2. Для этого используйте Google для strawberry query . Но, пожалуйста, убедитесь, что вы понимаете, как работает plain GROUP BY .

Ответ №2:

Присоединиться к дополнительному выбору таблиц, которые содержат только минимальное значение каждой группы

В этом примере. значение mygroup min (amt) возвращает элемент с наименьшим долларом для группы

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

 Select A.myGROUP, A.Amt
from mtest A
  INNER JOIN (Select myGroup, min(Amt) as minAmt from mtest group by mygroup) B
  ON B.myGroup=A.mygroup
  and B.MinAmt = A.Amt
  

Ответ №3:

ДА. Каждый отдельный ключ группы возвращается только один раз. Эту проблему нелегко решить. Запустите два разных запроса и впоследствии объедините результаты. ЕСЛИ это не вариант, создайте временную таблицу по минимальной цене для каждого шага объединения таблиц в запросе.