SQL – получить максимальный результат

Предположим, что существует табличное имя «test» ниже:

name value n1 1 n2 2 n3 3 

Теперь, я хочу получить имя, которое имеет максимальное значение, у меня есть некоторое решение ниже:

Решение 1:

 SELECT TOP 1 name FROM test ORDER BY value DESC 

раствор 2:

 SELECT name FROM test WHERE value = (SELECT MAX(value) FROM test); 

Теперь, надеюсь, вы используете операцию соединения, чтобы найти результат, например

 SELECT name FROM test INNER JOIN test ON... 

Может ли кто-нибудь помочь и объяснить, как это работает?

Если вы ищете JOIN, тогда

 SELECT T.name, T.value FROM test T INNER JOIN ( SELECT T1.name, T1.value , RANK() OVER (PARTITION BY T1.name ORDER BY T1.value) N FROM test T1 WHERE T1.value IN (SELECT MAX(t2.value) FROM test T2) )T3 ON T3.N = 1 AND T.name = T3.name 

FIDDLE DEMO

или

 select name, value from ( select name, value, row_number() over(order by value desc) rn from test ) src where rn = 1 

FIDDLE DEMO

Во-первых, обратите внимание, что решения 1 и 2 могут давать разные результаты, когда значение не является уникальным. Если в ваших тестовых данных будет дополнительная запись («n4», 3) , тогда решение 1 вернет либо «n3», либо «n4» , но решение 2 вернет оба.

Для решения с JOIN потребуются псевдонимы для таблицы, потому что, как вы начали, движок скажет неоднозначное имя столбца «name». : он не знал бы, следует ли принимать имя от первого или второго появления тестовой таблицы.

Вот способ завершить версию JOIN :

 SELECT t1.name FROM test t1 LEFT JOIN test t2 ON t2.value > t1.value WHERE t2.value IS NULL; 

Этот запрос берет каждую из записей и проверяет, существуют ли какие-либо записи с более высоким значением . Если нет, первая запись будет в результате. Обратите внимание на использование LEFT : это означает внешнее соединение, так что записи из t1 , которые не совпадают с t2 – на основе условия ON , не сразу отвергаются (как в случае с INNER ): на самом деле мы хотите отклонить все остальные записи, которые выполняются с WHERE .

Способ понять этот механизм состоит в том, чтобы посмотреть на вариант вышеприведенного запроса, в котором отсутствует WHERE и возвращается значение s обеих таблиц:

 SELECT t1.value, t2.value FROM test t1 LEFT JOIN test t2 ON t2.value > t1.value 

По вашим тестовым данным это вернет:

 t1.value t2.value 1 2 1 3 2 3 3 (null) 

Обратите внимание, что последняя запись не будет там, если соединение, в которое INNER JOIN . Но с внешним соединением теперь можно искать значения NULL и фактически получать эти записи в результате, которые будут исключены из INNER JOIN .

Обратите внимание, что этот запрос даст тот же результат, что и решение 2 при наличии повторяющегося значения s. Если вы хотите иметь только один результат, например, с решением 1, достаточно добавить TOP 1 после SELECT .

Вот скрипка .

Альтернатива чистым INNER JOIN

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

 SELECT TOP 1 t1.name FROM test t1 INNER JOIN (SELECT Max(value) AS value FROM test) t2 ON t2.value = t1.value; 

Но этот действительно очень похож на то, что вы сделали в решении 2. Здесь есть скрипка .

  • Элегантное решение для записи в базу данных, а также карту rfid несколько атомным способом
  • SQL Order by Custom CASE КОГДА заказ
  • SQL-запрос с использованием Pivot, когда поля не исправить
  • Как реализовать таблицу поиска для диапазона значений двух столбцов
  • как получить данные из базы данных SQL в Word 2010?
  • Ускорение массового вставки в SQL Server 2005
  • Изменение коллекции схем SQL Server
  • тип циклов в sql-сервере?
  • В чем преимущества использования VARCHAR (max), NVARCHAR (max) и VARBINARY (max) вместо TEXT, NTEXT и IMAGE?
  • Развертывание кода инфраструктуры сущности сначала с производственной базой данных
  • Создание пустой копии базы данных SQL Server 2012 на том же экземпляре
  • Давайте будем гением компьютера.