Получить максимум с другими данными

#sql #group-by #max

#sql #группировать по #максимум

Вопрос:

Я должен прийти и спросить об этом, потому что я уже зол, плачу и все такое, потому что это действительно убивает меня. Я ненавижу SQL. Но это должно быть сделано. Веб-сайт использует SQL.

У меня есть эти таблицы (сокращенные до необходимого, а не реального SQL):

 CREATE TABLE deliverer(d_id INT PRIMARY KEY, name VARCHAR(80));
CREATE TABLE article(a_id INT PRIMATY KEY, brand VARCHAR(80));
CREATE TABLE delivers(d_id FOREIGN KEY(deliverer), a_id FOREIGN KEY(article));
  

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

 SELECT brand, MAX(cnt)
FROM
(SELECT COUNT(a.a_id) AS cnt, a.brand, d.d_id, d.name
    FROM derliverer d, delivers l, article a
    WHERE a.a_id = l.a_id AND l.d_id = d.d_id
    GROUP BY a.brand, d.d_id, d.name)
GROUP BY brand;
  

Чего я действительно, действительно, действительно не понимаю в SQL, так это почему он не позволяет мне GROUP BY brand и SELECT d.name, d.d_id . Это действительно не имеет смысла.

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

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

1. Я думаю, что это был DB2 в рабочей среде, не уверен. Использование MySQL в тестировании.

Ответ №1:

Чего я действительно, действительно, действительно не понимаю в SQL, так это почему он не позволяет мне ГРУППИРОВАТЬ По брендам и ВЫБИРАТЬ d.name, d.d_id. Это действительно не имеет смысла.

Потому что, если вы это сделаете, количество будет для каждого отдельного d.name, d.d_id. Это не то, что вы хотите.

Вы определенно хотите прочитать несколько руководств о том, как работает group by.

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

В этом случае вам нужно что-то вроде:

 select brand_id, count(*) as top_deliverer, deliverer_id, deliverer.etc.
from some stuff
group by brand_id, deliverer_id, deliverere.etc
order by top_deliverer desc
  

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

1. Ну, это допустимо, но это не дает мне дополнительных данных, которые мне нужны. Мне нужно сгруппировать ny бренд, но также получить d.name с его помощью, без группировки по нему. Но max функция заставляет меня группировать по каждому столбцу.

2. Соедините его с исходной таблицей… Или используйте два отдельных запроса (вероятно, так будет лучше).

3. Продолжение: я соответствующим образом обновил свой ответ. И, основываясь на вашем ответе, вам определенно нужно прочитать об этом операторе group by, потому что вы полностью сбиты с толку тем, что он делает. Вам нужно группировать по каждому другому столбцу в большинстве баз данных, и в случае, если вы когда-нибудь решите, что это оптимизация «кодирования», использование подзапросов приведет к полному сканированию таблицы (что далеко не оптимально).

4. Мне неприятно спрашивать, но вы прочитали предложение group by, как было предложено, прежде чем отвечать на это? Я спрашиваю, потому что из вашего комментария следует, что вы все еще этого не понимаете. Подумайте об этом так: group by преобразует декартово соединение (посмотрите на свой запрос перед group by и агрегирует) в новый набор строк, используя агрегатные функции на основе полей в предложении. Ваше понимание, похоже, больше похоже на: group by волшебным образом возвращает все, что я хочу, независимо от полей, которые я хочу или передаю. (И мне жаль это говорить, но SQL — это не тот язык, который допускает подобную фантазию.)

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