Выбор записи с максимальным значением
В SQL Server 2008 у меня есть таблица CUSTOMERS, которая имеет два столбца:
ID, БАЛАНС
Как написать запрос, который выбирает идентификатор клиента с максимальным балансом "самым эффективным способом"?
Вариант 1: ORDER BY BALANCE and SELECT TOP(1)
→ слишком дорого.
Вариант 2: во-первых, Get MAX amount
, затем создайте другой запрос, в котором используется сумма, where clause
→ стоит слишком много и не кажется надежным.
Ответы
Ответ 1
Примечание. Неправильная ревизия этого ответа была отредактирована. Просмотрите все ответы.
Подзапрос в WHERE
для получения наибольшего BALANCE
агрегированного по всем строкам. Если несколько значений ID
разделяют это значение баланса, все они будут возвращены.
SELECT
ID,
BALANCE
FROM CUSTOMERS
WHERE BALANCE = (SELECT MAX(BALANCE) FROM CUSTOMERS)
Ответ 2
Что значит слишком дорого? Слишком много чего?
SELECT MAX(Balance) AS MaxBalance, CustomerID FROM CUSTOMERS GROUP BY CustomerID
Если таблица правильно проиндексирована (Баланс), и на ПК должен быть указатель, чем я не уверен, что вы имеете в виду слишком дорого или кажется ненадежным? Нет ничего ненадежного в совокупности, которую вы используете, и говорите ей об этом. В этом случае MAX()
делает именно то, что вы говорите, - ничего волшебного в этом нет.
Взгляните на MAX()
и если вы хотите отфильтровать его, используйте предложение HAVING
.
Ответ 3
Здесь есть опция, если у вас есть несколько записей для каждого Клиента и вы ищете последний баланс для каждого (скажем, они устарели):
SELECT ID, BALANCE FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DateModified DESC) as RowNum, ID, BALANCE
FROM CUSTOMERS
) C
WHERE RowNum = 1
Ответ 4
Скажем, для пользователя есть ревизия для каждой даты. Ниже приводится отчет о максимальном пересмотре каждой даты для каждого сотрудника.
select job, adate, rev, usr, typ
from tbl
where exists ( select 1 from ( select usr, adate, max(rev) as max_rev
from tbl
group by usr, adate
) as cond
where tbl.usr=cond.usr
and tbl.adate =cond.adate
and tbl.rev =cond.max_rev
)
order by adate, job, usr
Ответ 5
Ответ, на который ответил sandip giri, был правильным ответом, здесь аналогичный пример получения максимального id (PresupuestoEtapaActividadHistoricoId) после вычисления максимального значения (Base)
select *
from (
select PEAA.PresupuestoEtapaActividadId,
PEAH.PresupuestoEtapaActividadHistoricoId,
sum(PEAA.ValorTotalDesperdicioBase) as Base,
sum(PEAA.ValorTotalDesperdicioEjecucion) as Ejecucion
from hgc.PresupuestoActividadAnalisis as PEAA
inner join hgc.PresupuestoEtapaActividad as PEA
on PEAA.PresupuestoEtapaActividadId = PEA.PresupuestoEtapaActividadId
inner join hgc.PresupuestoEtapaActividadHistorico as PEAH
on PEA.PresupuestoEtapaActividadId = PEAH.PresupuestoEtapaActividadId
group by PEAH.PresupuestoEtapaActividadHistoricoId, PEAA.PresupuestoEtapaActividadId
) as t
where exists (
select 1
from (
select MAX(PEAH.PresupuestoEtapaActividadHistoricoId) as PresupuestoEtapaActividadHistoricoId
from hgc.PresupuestoEtapaActividadHistorico as PEAH
group by PEAH.PresupuestoEtapaActividadId
) as ti
where t.PresupuestoEtapaActividadHistoricoId = ti.PresupuestoEtapaActividadHistoricoId
)
Ответ 6
Это простой способ получить клиента с максимальным балансом:
SELECT
ID,
BALANCE
FROM CUSTOMERS
WHERE BALANCE = (SELECT MAX(BALANCE) FROM CUSTOMERS)