Ответ 1
SELECT Id, value
FROM Scores
WHERE value = (SELECT MAX(value) FROM Scores);
У меня есть следующая таблица:
Таблица: Результаты Что у меня:
+----+-------+ | 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), но только возвращает одну строку.
SELECT Id, value
FROM Scores
WHERE value = (SELECT MAX(value) FROM Scores);
Используйте быструю переменную:
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 оценивать каждую строку. Вот "баллы" с вашими данными образца (лучше ниже):
В MySQL вам нужно сделать это с помощью соединения или подзапроса:
select *
from t
where value = (select max(value) from t)
Используйте этот запрос:
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)