Выбор записи с максимальным значением

В 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)