2010-10-19 3 views
5

Wie können wir die zweitgrößte Marke oder was auch immer aus einer Tabelle auswählen, ohne die LIMIT zu verwenden? Ich weiß, dass es mit LIMIT möglich ist, aber ist es möglich, ohne das zu verwenden?Wählen Sie die zweitgrößte aus einer Tabelle ohne Limit

Angenommen, wir haben die Spalten ID und Marken.

+2

Was magst du an LIMIT nicht? – Unreason

+0

das war eine Interviewfrage;) – viMaL

+0

Ich denke, die Frage hätte sein können, es ohne ORDER BY und LIMIT zu lösen. da order by die Sortierung in O (n * log (n)) erfordert, während der Interviewer nach O (n) suchte – dharm0us

Antwort

7

Angenommen, die Markierungen sind eindeutig, folgende Abfrage gibt Ihnen die zweitgrößte Marke.

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

Um den gesamten Datensatz zu bekommen, man könnte diese wickeln in einem 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

Für MySql: * aus atable where marks = (max (Marken) als secmax von atable where marks dharm0us

+0

ist das '(SELECT MAX (Marken) FROM ATable)' eingelöst oder wird diese Abfrage für jede Zeile ausgeführt? weil dieser Ansatz in einer Tabelle mit etwa 1000 Zeilen sehr langsam ist, danke –

+1

@Gabriel - beachten Sie, dass die Abfrage immer nur eine einzelne Zeile zurückgibt. Bei einer ordnungsgemäß indizierten Tabelle führt dies zu einer Indexsuche und einer Indexsuche. Dies sollte kein Problem für jede Datenbank-Engine sein, die es wert ist. –

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

Sie ein

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

aber LIMIT dann der oben sollte besser durchführen tun könnte, Also ist die Frage, warum Sie es nicht mögen?

0

Wenn Sie eine ganze Zeile (alle Spalten) benötigen, wird diese Aufgabe erledigt. Außerdem gibt es immer nur eine Zeile zurück, auch wenn es mehrere mit dem gleichen zweiten Maximalwert gibt.

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

Wenn Sie mit echten zweiten Maximalwert nur eine Zeile wollen, sollten Sie verwenden:

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

Es könnte auch von CTE (SQL Server 2005+) erfolgen:

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

Wenn Sie alle Zeilen mit den 2. Max-Markierungen sehen möchten, entfernen Sie einfach TOP 1 von der vorherigen Abfrage.

Verwandte Themen