#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. Я этого не сделал, извините. Я слишком занят этим, я отдохну и прочитаю ваши рекомендации. Может быть, я просто хотел найти решение сейчас, потому что это действительно заводит меня. Спасибо за ваши усилия.