Вернуть все строки с значением "MAX" в SQL?

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

Таблица: Результаты Что у меня:

+----+-------+
| Id | value |
+----+-------+
|  1 |   300 |
|  2 |   300 |
|  3 |   300 |
|  4 |   100 |
|  5 |   200 |
+----+-------+

Что мне нужно:

+----+-------+
| Id | value |
+----+-------+
|  1 |   300 |
|  2 |   300 |
|  3 |   300 |
--------------

Как бы я захватил "все" верхние оценки id 1, 2, 3 в SQL. Я начал использовать MAX (в mysql), но только возвращает одну строку.

Ответ 1

SELECT Id, value
    FROM Scores
    WHERE value = (SELECT MAX(value) FROM Scores);

Ответ 2

Используйте быструю переменную:

SELECT @max := max(value) from scores;
SELECT id, value FROM scores WHERE value = @max;

или еще: (и я обычно в стойкой оппозиции к подзапросам, но это без проблем.

SELECT id, value FROM
scores
INNER JOIN (Select max(value) as value from scores) as max USING(value)

Обратите внимание, что они оба предпочтительнее более базового `WHERE value = (подзапрос), потому что для каждого из них запрос на поиск значения MAX выполняется ровно один раз (абсолютная гарантия для этого - это то, почему я предпочитаю переменную- основанного на решении). С версией подзапроса (в WHERE, а не JOIN) этот запрос, вероятно, будет выполняться один раз в строке.

Я провел анализ запросов с помощью EXPLAIN EXTENDED, и метод INNER JOIN, вероятно, является наиболее кратким и оптимальным из всех предложений (предположим, что вы находитесь в среде, где использование переменных MySQL слишком громоздко, я все еще думаю, что это чистый).

производительность:

С тех пор, как произошло какое-то интересное обсуждение, я решил поучаствовать в этом и оценить эти вещи (overkill, я знаю, но веселые и полезные знания по более крупным проблемам). Существует несколько аналитических трюков для обнаружения полного сканирования таблицы; добавив WHERE (@foo := @foo + 1) к подзапросам, о которых идет речь, затем установите @foo на 0, запустив запрос и увидев, что такое @foo. Это не конечная метрика всех запросов, но она может быть довольно информативной о том, как часто вы просите MySQL оценивать каждую строку. Вот "баллы" с вашими данными образца (лучше ниже):

  • @ctrahey (оба): 5 (сканирование один раз, чтобы найти MAX)
  • @Joe Stefanelli: 25 (сканирование раз в строке (5 * 5))
  • @Jocelyn: 17 (я не могу объяснить это, но я хотел бы узнать, почему: -)

Ответ 3

В MySQL вам нужно сделать это с помощью соединения или подзапроса:

select *
from t
where value = (select max(value) from t)

Ответ 4

Используйте этот запрос:

SELECT id, value
FROM Scores
WHERE value>=ALL(SELECT value FROM Scores)

Документация: Подзапросы со ALL

Оптимизация подзапросов:

MySQL улучшает выражения следующей формы с выражением включая MIN() или MAX(), если значения NULL или пустые множества не являются участие:

value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery)

Например, это предложение WHERE:

WHERE 5 > ALL (SELECT x FROM t)

может быть обработан оптимизатором следующим образом:

WHERE 5 > (SELECT MAX(x) FROM t)