2010-10-19 17 views
5

Come possiamo selezionare il secondo marchio più grande o qualsiasi cosa da una tabella senza utilizzare il LIMIT? So che è possibile usare LIMIT, ma è possibile senza usarlo?Seleziona il secondo più grande da una tabella senza limite

Supponiamo di avere le colonne id e segni.

+2

Che cosa non ti piace di LIMIT? – Unreason

+0

quella era una domanda di intervista;) – viMaL

+0

Penso che la domanda avrebbe potuto essere risolverlo senza utilizzare ORDER BY e LIMIT. poiché l'ordine richiede l'ordinamento in O (n * log (n)), mentre l'intervistatore stava cercando O (n) – dharm0us

risposta

7

I segni presupposti sono univoci, la query seguente indica il secondo segno più grande.

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

Per ottenere l'intero record, si potrebbe avvolgere questo in 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

Per MySql: selezionare * da atable dove marks = (selezionare max (marks) come secmax da atable dove marks < (selezionare max (segni) da atable)) – dharm0us

+0

è il '(SELEZIONA MAX (segni) DA ATable)' che viene incassato o questa query viene eseguita per ogni riga? perché questo approccio è molto lenta su una tabella con circa 1000 righe, grazie –

+1

@Gabriel - nota che la query restituisce sempre e solo una singola riga. Su una tabella indicizzata corretta, ciò comporta una scansione dell'indice e una ricerca indice. Questo non dovrebbe essere un problema per qualsiasi motore di database che valga la pena. –

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

Si potrebbe fare un

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

ma limite dovrebbe svolgere meglio allora quanto sopra, quindi la domanda è perché non ti piace?

0

Se è necessaria una riga intera (tutte le colonne), questa operazione verrà eseguita. Inoltre, restituirà sempre solo una riga, anche se ce ne sono diverse con lo stesso 2 ° valore massimo.

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

Se si desidera solo una riga con il valore reale 2 ° max, si dovrebbe usare:

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

Potrebbe essere fatto da CTE (SQL Server 2005 +) troppo:

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

Se si desidera vedere tutte le righe con i secondi segni massimi, rimuovere TOP 1 dalla query precedente.

Problemi correlati