Obtener el segundo valor más alto en una tabla

14
id value
1   50
2   60
3   55

select max(value) from tablename;

En general, sabemos que obtendremos 60, pero necesito el siguiente valor 55.

¿Cómo obtengo el valor 55 usando SQL?

Mahfuz Morshed
fuente

Respuestas:

24

Suponiendo que el valor más alto solo ocurre una vez, otra forma sería usar OFFSET(SQL Server 2012 o posterior):

SELECT * 
FROM tablename
ORDER BY column DESC 
OFFSET 1 ROW 
FETCH NEXT 1 ROW ONLY;
Renato Afonso
fuente
23

Para obtener el segundo valor distinto más alto en la tabla, puede usar

SELECT MIN(value)
FROM   (SELECT DISTINCT TOP (2) value
        FROM   tablename
        ORDER  BY value DESC)T
/*If only one distinct value return nothing. */
HAVING MIN(value) <> MAX(value);
Martin Smith
fuente
13

Una solución genérica puede ser la siguiente:

;WITH CTE AS
(
    SELECT
        Col1
        , Col2
        , <AnyColumns>
        , ROW_NUMBER() OVER (ORDER BY <AnyColumns>) AS RowNum
    FROM <YourTable>
    WHERE <YourCondition>
)
SELECT *
FROM CTE
WHERE RowNum = 2 -- Or any condition which satisfies your problem

Aquí también puede definir el rango como RowNum >= 10 AND RowNum <= 20. Y le dará de 10 a 20 filas con todas las columnas requeridas.

SwapnilBhate
fuente
7

Tienes el truco principal habitual, como:

select top 1 *
from (
    select top 2 *
    from my_table
    order by value desc
    ) t 
order by value asc 

O también puede usar CTE como:

with CTE as
(
select value, ROW_NUMBER() over(order by value desc) as ord_id
from my_table
)
select value
from CTE
where ord_id = 2

O, si usa una versión reciente de SQLServer (> = 2012), la función de retraso .

SELECT  top 1  lag(value, 1,0) OVER (ORDER BY value)  
FROM my_table
order by value desc
irimias
fuente
5

Haré así:

SELECT MAX(value)
FROM tablename
WHERE value < (SELECT MAX(value)
               FROM tablename)
Amo
fuente
1

También puede usar la ROW_NUMBER()función de ventanas. Si desea obtener la segunda entrada cuando lo ordena su valor objetivo, puede hacer lo siguiente:

SELECT value 
FROM (
    SELECT 
        ROW_NUMBER() OVER (PARTITION BY NULL ORDER BY value DESC) as RN,
        value
    FROM my_table
) d
WHERE RN = 2

Ahora, si desea obtener el segundo valor más alto y tiene duplicados, es posible que desee agrupar por la entrada de valor para que solo obtenga valores distintos.

SELECT value 
FROM (
    SELECT 
        ROW_NUMBER() OVER (PARTITION BY NULL ORDER BY value DESC) as RN,
        value
    FROM my_table
    GROUP BY value
) d
WHERE RN = 2

Debería poder modificar este enfoque para incluir un MIN(id)en la selección interna si necesita conocer la ID del primer registro con el segundo valor más alto (suponiendo que tuviera un conjunto de datos con dos 60 y dos 55)

CodeMonkey
fuente
55
Para la segunda más alta es más fácil de reemplazar simplemente ROW_NUMBER()con DENSE_RANK()- usted también consigue todas las otras columnas de forma gratuita. No es necesario usar GROUP BY.
ypercubeᵀᴹ