2010-10-19 3 views
5

Comment pouvons-nous sélectionner la deuxième plus grande marque ou quelque chose d'un tableau sans utiliser la LIMIT? Je sais que c'est possible en utilisant LIMIT, mais est-ce possible sans l'utiliser? Supposons que nous ayons les colonnes id et les marques.Sélectionnez la deuxième plus grande d'une table sans limite

+2

Qu'est-ce qui ne vous plaît pas à propos de LIMIT? – Unreason

+0

qui était une question d'entrevue;) – viMaL

+0

Je pense que la question aurait pu être de le résoudre sans utiliser ORDER BY et LIMIT. depuis order par require trier dans O (n * log (n)), alors que l'enquêteur recherchait O (n) – dharm0us

Répondre

7

En supposant que les marques sont uniques, la requête suivante vous donne la deuxième plus grande marque.

SELECT MAX(marks) 
FROM  ATable 
WHERE marks < (SELECT MAX(marks) FROM ATable) 

Pour obtenir l'ensemble du dossier, vous pouvez envelopper cela dans un INNER JOIN

SELECT t1.* 
FROM ATable t1 
     INNER JOIN (
      SELECT marks = MAX(marks) 
      FROM  ATable 
      WHERE marks < (SELECT MAX(marks) FROM ATable) 
     ) t2 ON t2. marks = t1.marks 
+0

Pour MySql: select * from atable où marques = (sélectionnez max (marques) comme secmax de atable où marques < (Sélectionnez max (marques) de atable)) – dharm0us

+0

est le '(SELECT MAX (marques) FROM ATable)' être encaissé ou cette requête s'exécute pour chaque ligne? parce que cette approche est très lente sur une table avec environ 1000 lignes, merci –

+1

@Gabriel - notez que la requête ne renvoie jamais qu'une seule ligne. Sur une table indexée appropriée, cela se traduit par une recherche d'index et une recherche d'index. Cela ne devrait pas être un problème pour tout moteur de base de données qui en vaut la peine. –

1
select max(number), id 
from <tableName> 
where number < (select max(number) from <tableName>) 
0

Vous pouvez faire un

SELECT MAX(marks) FROM TABLE 
WHERE marks NOT IN (SELECT MAX(marks) FROM TABLE) 

mais LIMIT doit effectuer mieux que ce qui précède, alors la question est pourquoi vous ne l'aimez pas?

0

Si vous avez besoin d'une ligne entière (toutes les colonnes), celle-ci le fera. De plus, il retournera toujours une seule ligne, même s'il y en a plusieurs avec la même 2ème valeur max.

Select top 1 * 
    From (Select Top 2 * 
      From TABLE 
     Order By marks desc 
     ) a 
Order By marks asc 

Si vous voulez seulement une ligne avec une réelle 2ème valeur maximale, vous devez utiliser:

select Top 1 * 
    from TABLE 
where marks < (select max(marks) from TABLE) 
Order by max desc 

Il pourrait être fait par CTE (SQL Server 2005+) aussi:

;With a as 
(
Select Dense_Rank() over (order by marks desc) as nRank, 
     * 
    From TABLE 
) 
Select Top 1 * 
    from a 
Where nRank=2 

Si vous souhaitez voir toutes les lignes avec les marques max 2, supprimez simplement TOP 1 de la requête précédente.

Questions connexes