SQL – получить максимальный результат
Предположим, что существует табличное имя «test» ниже:
name value n1 1 n2 2 n3 3
Теперь, я хочу получить имя, которое имеет максимальное значение, у меня есть некоторое решение ниже:
Решение 1:
- Подключить созданную MSSQL базу данных с помощью PostgreSQL
- Каковы основные различия между Sql Server 2005 и Sql Server 2008?
- Можем ли мы передать имя базы данных в SQL-запросе в качестве параметра?
- Можно ли заказать любой столбец с параметром хранимой процедуры в SQL Server?
- DacPac исключает пользователей и логинов при экспорте или импорте
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...
Может ли кто-нибудь помочь и объяснить, как это работает?
- Как обновить таблицу, не импортированную EDMX в проект C #
- Проект Visual Studio 2013+ DB - Partial Schema / Import Partial DB Project
- SQL Server: обновление таблицы отчетов в режиме реального времени
- Отказоустойчивое условное соединение SQL, см. Объяснение
- Как добавить команду GETDATE () в поле ntext?
- jquery сортируемая база данных обновлений с использованием coldfusion
- Определите, какой пользователь удалил базу данных SQL Server?
- Как бы один список баз данных на SQL Server, а не по запросу, но с помощью вызова c #?
Если вы ищете 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. Здесь есть скрипка .