Qual è la query SQL più semplice per trovare il secondo valore più grande?


168

Qual è la query SQL più semplice per trovare il secondo valore intero più grande in una colonna specifica?

Forse ci sono valori duplicati nella colonna.


usa offset per questo scopo ... seleziona l'estensione da [dbo]. [Impiegati] ordina per estensione desc offset 2 righe recupera solo 1 righe successive
Jinto John

Risposte:


294
SELECT MAX( col )
  FROM table
 WHERE col < ( SELECT MAX( col )
                 FROM table )

7
Matt e la risposta di Vinoy si occupano anche dei duplicati. Supponiamo che il valore più grande venga ripetuto, quindi l'uso della risposta di Matt produrrà il secondo valore più grande corretto, mentre se hai usato l' approccio top 2 desc e min , potresti invece ottenere il valore più grande.
Pankaj Sharma,

E se ci fossero più di un secondo in più ... Quindi questo non darà tutte le Tuple
Parth Satra,

2
grazie, usato questo per trovare il secondo ultimo appuntamento qui
shaijut

Molto meglio del mio approccio usando ORDER_BY e LIMIT per l'affermazione interna
andig

Nota che questo non restituirà un risultato se non ci sono record prima di quello richiesto.
andig

61
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);

31

In T-Sql ci sono due modi:

--filter out the max
select max( col )
from [table]
where col < ( 
    select max( col )
    from [table] )

--sort top two then bottom one
select top 1 col 
from (
    select top 2 col 
    from [table]
    order by col) topTwo
order by col desc 

In Microsoft SQL il primo modo è due volte più veloce del secondo, anche se la colonna in questione è raggruppata.

Questo perché l'operazione di ordinamento è relativamente lenta rispetto alla scansione della tabella o dell'indice maxutilizzata dall'aggregazione.

In alternativa, in Microsoft SQL 2005 e versioni successive è possibile utilizzare la ROW_NUMBER()funzione:

select col
from (
    select ROW_NUMBER() over (order by col asc) as 'rowNum', col
    from [table] ) withRowNum 
where rowNum = 2

20

Vedo qui sia alcune soluzioni specifiche di SQL Server sia alcune soluzioni specifiche di MySQL, quindi potresti voler chiarire quale database ti serve. Tuttavia, se dovessi indovinare, direi SQL Server poiché questo è banale in MySQL.

Vedo anche alcune soluzioni che non funzioneranno perché non tengono conto della possibilità di duplicati, quindi fai attenzione a quali accetti. Infine, ne vedo alcuni che funzioneranno ma che eseguiranno due scansioni complete della tabella. Vuoi assicurarti che la 2a scansione stia guardando solo 2 valori.

SQL Server (pre-2012):

SELECT MIN([column]) AS [column]
FROM (
    SELECT TOP 2 [column] 
    FROM [Table] 
    GROUP BY [column] 
    ORDER BY [column] DESC
) a

MySQL:

SELECT `column` 
FROM `table` 
GROUP BY `column` 
ORDER BY `column` DESC 
LIMIT 1,1

Aggiornare:

SQL Server 2012 ora supporta una sintassi OFFSET / FETCH molto più chiara (e standard ):

SELECT TOP 2 [column] 
FROM [Table] 
GROUP BY [column] 
ORDER BY [column] DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;

Questo è quello che speravo di vedere. La risposta accettata diventa brutta se ne hai bisogno per funzionare per qualcuno n. Questo è quello che prova.
Robin Maben,

@RobinMaben Robin, che ne dici dello scenario in cui si ripete il valore più grande? Supponiamo che una colonna contenga i numeri da 1 a 100 ma 100 venga ripetuto due volte. Quindi questa soluzione produrrà il secondo valore più grande come 100, che sarà errato. Destra?
Pankaj Sharma,

1
@PankajSharma no, funzionerà ancora, a causa della clausola GROUP BY
Joel Coehoorn,

Questo è il modo standard per farlo. La risposta accettata dovrebbe essere aggiornata a questa.
Guilherme Melo,

1
Viene visualizzato un errore che indica che non è possibile utilizzare TOPe OFFSETnella stessa query.
Spurio

15

Suppongo che tu possa fare qualcosa del tipo:

SELECT * FROM Table ORDER BY NumericalColumn DESC LIMIT 1 OFFSET 1

o

SELECT * FROM Table ORDER BY NumericalColumn DESC LIMIT (1, 1)

a seconda del server del database. Suggerimento: SQL Server non ha LIMIT.


update- SQL Server 2012 ha aggiunto una clausola offset / fetch simile a quella sopra dbadiaries.com/…
iliketocode

Supponiamo di avere 2 elementi con lo stesso valore ma anche l'elemento più grande. Immagino che tu debba fareOFFSET 2
Kangkan il

L'aggiunta della clausola GROUP BY soddisferà la condizione duplicata in questo.
Saif,

7

Il modo più semplice sarebbe quello di ottenere il secondo valore da questo set di risultati nell'applicazione:

SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2

Ma se devi selezionare il secondo valore usando SQL, che ne dici di:

SELECT MIN(value) FROM (SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2) AS t

1
Hai eseguito questo su SQL Server?
Craig,

1
@Craig - LIMITè la sintassi di MySql, la domanda non specifica una versione di SQL.
Keith,


4

Una query molto semplice per trovare il secondo valore più grande

SELECT `Column` FROM `Table` ORDER BY `Column` DESC LIMIT 1,1;

4

MSSQL

SELECT  *
  FROM [Users]
    order by UserId desc OFFSET 1 ROW 
FETCH NEXT 1 ROW ONLY;

MySQL

SELECT  *
  FROM Users
    order by UserId desc LIMIT 1 OFFSET 1

Non sono necessarie query secondarie ... salta una riga e seleziona le seconde righe dopo l'ordine in ordine decrescente


3
SELECT MAX(Salary) FROM Employee WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee )

Questa query restituirà lo stipendio massimo, dal risultato, che non contiene lo stipendio massimo dalla tabella generale.


2
Puoi modificare per spiegare in che modo questo è significativamente diverso dalle vecchie risposte?
Nathan Tuggy,

3

Vecchia domanda che conosco, ma questo mi ha dato un piano esecutivo migliore:

 SELECT TOP 1 LEAD(MAX (column)) OVER (ORDER BY column desc)
 FROM TABLE 
 GROUP BY column

3

Questo è un codice molto semplice, puoi provare questo: -

es: nome tabella = test

salary 

1000
1500
1450
7500

Codice MSSQL per ottenere il 2 ° valore più grande

select salary from test order by salary desc offset 1 rows fetch next 1 rows only;

qui "offset 1 righe" significa la seconda riga della tabella e "recupera solo le 1 righe successive" è per mostrare solo quella 1 riga. se non usi "recupera solo 1 riga successiva", mostra tutte le righe della seconda riga.


La risposta più ottimizzata e rispettosa delle risorse. Ho risparmiato un bel po 'di tempo utilizzandolo nella mia subquery. Grazie.
vibs2006,

2

select * from (select ROW_NUMBER() over (Order by Col_x desc) as Row, Col_1
    from table_1)as table_new tn inner join table_1 t1
    on tn.col_1 = t1.col_1
where row = 2

Spero che questo aiuto per ottenere il valore per qualsiasi riga .....


2

Il più semplice di tutti

select sal from salary order by sal desc limit 1 offset 1

1
select min(sal) from emp where sal in 
    (select TOP 2 (sal) from emp order by sal desc)

Nota

sal è col nome
emp è il nome della tabella


1

Tom, credi che questo fallirà quando c'è più di un valore restituito nella select max([COLUMN_NAME]) from [TABLE_NAME]sezione. cioè dove ci sono più di 2 valori nel set di dati.

Una leggera modifica alla tua query funzionerà -

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] **IN** 
  ( select max([COLUMN_NAME]) from [TABLE_NAME] )

1
select max(COL_NAME) from TABLE_NAME where COL_NAME in 
    (select COL_NAME from TABLE_NAME where COL_NAME < (select max(COL_NAME) from TABLE_NAME));

la sottoquery restituisce tutti i valori diversi dal più grande. selezionare il valore massimo dall'elenco restituito.


1
select col_name
from (
    select dense_rank() over (order by col_name desc) as 'rank', col_name
    from table_name ) withrank 
where rank = 2

1
SELECT 
    * 
FROM 
    table 
WHERE 
    column < (SELECT max(columnq) FROM table) 
ORDER BY 
    column DESC LIMIT 1

1

È il modo più esotico:

SELECT
      Column name
FROM
      Table name 
ORDER BY 
      Column name DESC
LIMIT 1,1

1
select age from student group by id having age<(select max(age) from student)order by age limit 1

1

Come hai menzionato valori duplicati. In tal caso, è possibile utilizzare DISTINCT e GROUP BY per scoprire il secondo valore più alto

Ecco un tavolo

stipendio

:

inserisci qui la descrizione dell'immagine

RAGGRUPPA PER

SELECT  amount FROM  salary 
GROUP by amount
ORDER BY  amount DESC 
LIMIT 1 , 1

DISTINCT

SELECT DISTINCT amount
FROM  salary 
ORDER BY  amount DESC 
LIMIT 1 , 1

Prima porzione di LIMIT = indice iniziale

Seconda porzione di LIMIT = quanti valori


1
SELECT MAX(sal) FROM emp
WHERE sal NOT IN (SELECT top 3 sal FROM emp order by sal desc )

questo restituirà il terzo più alto sal della tabella emp


1
select max(column_name) from table_name
where column_name not in (select max(column_name) from table_name);

non in è una condizione che esclude il valore più alto di nome_colonna.

Riferimento: intervista al programmatore


0

Qualcosa come questo? Non l'ho provato, però:

select top 1 x
from (
  select top 2 distinct x 
  from y 
  order by x desc
) z
order by x


0

Utilizzando una query correlata:

Select * from x x1 where 1 = (select count(*) from x where x1.a < a)

0
select * from emp e where 3>=(select count(distinct salary)
    from emp where s.salary<=salary)

Questa query seleziona il massimo di tre stipendi. Se due emp ricevono lo stesso stipendio, ciò non influisce sulla query.


0
select top 1 MyIntColumn from MyTable
where
 MyIntColumn <> (select top 1 MyIntColumn from MyTable order by MyIntColumn desc)
order by MyIntColumn desc

0

Funziona in MS SQL:

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] < 
 ( select max([COLUMN_NAME]) from [TABLE_NAME] )
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.