Выберите одно значение из группы на основе порядка из других столбцов

проблема

Предположим, у меня есть эта таблица (tabиграть на скрипке имеется) .Я»

| g | a | b |     v |
---------------------
| 1 | 3 | 5 |   foo |
| 1 | 4 | 7 |   bar |
| 1 | 2 | 9 |   baz |
| 2 | 1 | 1 |   dog |
| 2 | 5 | 2 |   cat |
| 2 | 5 | 3 | horse |
| 2 | 3 | 8 |   pig |

м группировки строк поgи для каждой группы я хочу одно значение из столбцаv, Тем не менее, я нене хочулюбой значение, но я хочу значение из строки с максимальнымaи из всех тех, с максимальнымb, Другими словами, мой результат должен быть

| 1 |   bar |
| 2 | horse |
Текущее решение

Я знаю запрос для достижения этой цели:

SELECT grps.g,
(SELECT v FROM tab
 WHERE g = grps.g
 ORDER BY a DESC, b DESC
 LIMIT 1) AS r
FROM (SELECT DISTINCT g FROM tab) grps
Вопрос

Но я считаю этот запрос скорееуродливый, Главным образом потому, что он используетзависимый подзапрос, который чувствует себя как настоящий убийца производительности. Поэтому мне интересно, есть ли более простое решение этой проблемы.

Ожидаемые ответы

Наиболее вероятным ответом на этот вопрос, который я ожидаю, будет какое-то дополнение или исправление для MySQL (или MariaDB), которое предоставляет такую возможность. Но я'Я буду приветствовать и другие полезные идеи. Все, что работает без зависимого подзапроса, будет рассматриваться как ответ.

Если ваше решение работает только для одного столбца заказа, т.е.т различитьcat а такжеhorseне стесняйтесь предлагать этот ответ, так как я ожидаю, что он все еще будет полезен для большинства случаев использования. Например,100*a+b было бы вероятным способом упорядочить вышеуказанные данные по обоим столбцам, при этом все еще используя только одно выражение.

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

Результаты тестов

Поскольку довольно сложно сравнивать разные ответы, просто взглянув на них, ямы проверили некоторые тесты на них. Это было запущено на моем рабочем столе с использованием MySQL 5.1. Выигранные номеране сравнить ни с какой другой системой, только между собой. Вы, вероятно, должны проводить свои собственные тесты с реальными данными, если производительность имеет решающее значение для вашего приложения. Когда приходят новые ответы, я могу добавить их в свой сценарий и перезапустить все тесты.

100 000 наименований, 1000 групп на выбор, InnoDb:0,166 с дляMvG (из вопроса)0,520 сRichardTheKiwi2.199 дляxdazz19,24 дляДемс (последовательные подзапросы)48,72 с дляacatt100 000 наименований, 50 000 групп на выбор, InnoDb:0,356 сxdazz0,640 сRichardTheKiwi0,764 дляMvG (из вопроса)51,50 дляacattслишком долго заДемс (последовательные подзапросы)100 000 наименований, 100 групп на выбор, InnoDb:0,163 сMvG (из вопроса)0,523 сRichardTheKiwi2.072s дляДемс (последовательные подзапросы)17,78 сxdazz49,85 сacatt

Так что, похоже, мое собственное решение покавсе так плохо, даже с зависимым подзапросом. Удивительно, но решение acatt, которое также использует зависимый подзапрос и которое я бы поэтому рассмотрел примерно так же, работает намного хуже. Возможно, что-то оптимизатор MySQL может 'т справиться с. Предлагаемое RichardTheKiwi решение, похоже, также имеет хорошую общую производительность. Два других решения сильно зависят от структуры данных. Со многими группами малые группы, xdazz ' Подход превосходит все остальные, в то время как решение Dems работает лучше (хотя все еще не исключительно хорошо) для нескольких больших групп.

Ответы на вопрос(4)

Ваш ответ на вопрос