Dans SQL Server 2008, j'ai une table CLIENTS qui a deux colonnes comme:
ID, BALANCE
Comment puis-je écrire la requête qui sélectionne l'ID du client qui a le solde maximum, " de la manière la plus efficace "?
Option 1: ORDER BY BALANCE and SELECT TOP(1)
-> coûte trop cher.
Option 2: premièrement Get MAX amount
, puis effectuez une autre requête utilisant le montant indiqué dans where clause
-> coûte trop cher et ne semble pas fiable.
Note: Une révision incorrecte de cette réponse a été supprimée. S'il vous plaît examiner toutes les réponses.
Une sous-sélection dans la clause WHERE
pour récupérer le plus grand nombre BALANCE
agrégé sur toutes les lignes. Si plusieurs valeurs ID
partagent la même valeur, elles seront toutes renvoyées.
SELECT
ID,
BALANCE
FROM CUSTOMERS
WHERE BALANCE = (SELECT MAX(BALANCE) FROM CUSTOMERS)
Voici une option si vous avez plusieurs enregistrements pour chaque client et recherchez le dernier solde pour chacun (disons qu'il s'agit d'enregistrements datés):
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
Que voulez-vous dire coûte trop cher? Trop quoi?
SELECT MAX(Balance) AS MaxBalance, CustomerID FROM CUSTOMERS GROUP BY CustomerID
Si votre table est correctement indexée (balance) et qu'il doit y avoir un index sur le PK, je ne suis pas sûr de ce que vous voulez dire par coûts trop élevés ou semble peu fiable? Il n’ya rien de douteux dans l’agrégat que vous utilisez et que vous lui dites de faire. Dans ce cas, MAX()
fait exactement ce que vous lui demandez de faire - il n'y a rien de magique à ce sujet.
Jetez un coup d'œil à MAX()
et si vous souhaitez le filtrer, utilisez la clause HAVING
.
Dites, pour un utilisateur, il y a une révision pour chaque date. Ce qui suit ramassera l'enregistrement pour la révision maximale de chaque date pour chaque employé.
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
La requête répondu par sandip giri était la bonne réponse, voici un exemple similaire qui obtient l'identifiant maximal (PresupuestoEtapaActividadHistoricoId), après avoir calculé la valeur maximale (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
)