Sql максимальное значение в группе

Как получить строки, содержащие максимальное значение для каждого сгруппированного набора?

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

учитывая таблицу, подобную приведенной ниже, с столбцами person, group и age, как бы вы получили самого старого человека в каждой группе? (Галстук в группе должен дать первый алфавитный результат)

желаемому результату set:

17 ответов

есть супер-простой способ сделать это в mysql:

это работает, потому что в mysql вам разрешено не aggregate non-group-BY columns, в этом случае mysql просто возвращает первый row. Решение: первого порядка данных, таких, что для каждой группы строки вы хотите, является первым, затем группы столбцов значение.

вы избегаете сложных подзапросов, которые пытаются найти max() etc, а также проблемы возврат нескольких строк, когда есть более одного с тем же максимальным значением (как и другие ответы)

Примечание: это mysql-только решение. Все другие базы данных, которые я знаю, выдадут синтаксическую ошибку SQL с сообщением "неагрегированные столбцы не перечислены в предложении group by" или аналогичном. Потому что это решение использует без документов поведение, более осторожный может включить тест, чтобы утверждать, что он остается работа должна будущая версия MySQL изменить это поведение.

обновление версии 5.7:

начиная с версии 5.7, в sql-mode установка включает в себя ONLY_FULL_GROUP_BY по умолчанию, поэтому, чтобы сделать эту работу, вы должны не есть эта опция (отредактируйте файл опции для сервера, чтобы удалить этот параметр).

как работает:

он соответствует каждой строке из o все строки b С тем же значением в столбце Group и большее значение в столбце Age . Любая строка из o не имея максимального значения своей группы в столбце Age будет соответствовать одной или нескольким строкам из b .

Читайте также:  Как продлить интернет на йоте

на LEFT JOIN делает его соответствовать самому старому человеку в группе (включая людей, которые одиноки в своей группе) с полным рядом NULL С b ("нет самого большого возраста в группе").
используя INNER JOIN делает эти строки не совпадают, и они игнорируются.

на WHERE предложение сохраняет только строки, имеющие NULL s в полях, извлеченных из b . Они-старейшие представители каждой группы.

дополнительная литература

мое простое решение для SQLite (и, вероятно, MySQL):

однако он не работает в PostgreSQL и, возможно, на некоторых других платформах.

в PostgreSQL вы можете использовать DISTINCT ON статья:

вы можете присоединиться к подзапросу, который тянет MAX(Group) и Age . Этот метод переносим в большинстве СУБД.

используя метод ранжирования.

решение axiac-это то, что сработало лучше всего для меня в конце. Однако у меня была дополнительная сложность: вычисленное "максимальное значение", полученное из двух столбцов.

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

мне пришлось выполнить левое соединение два раза, чтобы получить это поведение:

надеюсь, что это помогает! Думаю, должен быть лучший способ сделать это. хотя.

Использование Ctes-Общие Табличные Выражения:

Не уверен, что MySQL имеет функцию row_number. Если это так, вы можете использовать его, чтобы получить желаемый результат. В SQL Server вы можете сделать что-то похожее на:

мое решение работает, только если вам нужно получить только один столбец, однако для моих нужд было лучшее решение, найденное с точки зрения производительности (он использует только один запрос!):

он использует GROUP_CONCAT для создания упорядоченного списка concat,а затем подстроки только к первому.

вы также можете попробовать

Читайте также:  1 Дюйм это 2 54 сантиметра

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

пусть имя таблицы будет people

Если ID (и все coulmns) необходим из mytable

вот как я получаю N максимальных строк на группу в mysql

customer(c_id number,c_st vchar) – ид покупателя и штат;

order(o_id number,c_id number) – ид заказа и ид покупателя.

Задача "вывести заказчиков, с самым большим количеством заказов в каждом штате". Количество для каждого заказчика нашел:

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

2 ответа 2

Для получения строго одного покупателя, с максимальным количеством (даже если с одинаковым максимальным количеством есть несколько покупателей) можно посчитать строки в нужном порядке и отобрать первые из них:

Для поиска всех покупателей с одинаковым максимальным количеством в вышеприведенном запросе надо заменить функцию row_number() на функцию rank()

У меня есть следующая SQL таблица, со следующими данными:

И в следующем запросе нужно изменить ActionLevel таким образом он будет отражать

для всех параметров в каждом GroupID .

Так что, если у меня есть группа с параметрами «Местность» и «Вес», ActionLevel должно быть 3.

Любая помощь будет оценена.

Если я не ошибаюсь, в понимании ваших требований, то мы надеемся, что это будет работать.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock detector