Zdobądź drugą najwyższą wartość w tabeli

14
id value
1   50
2   60
3   55

select max(value) from tablename;

Ogólnie wiemy, że otrzymamy 60, ale potrzebuję następnej wartości 55.

Jak uzyskać wartość 55 za pomocą SQL?

Mahfuz Morshed
źródło

Odpowiedzi:

24

Zakładając, że najwyższa wartość występuje tylko raz, innym sposobem byłoby użycie OFFSET(SQL Server 2012 lub nowszy):

SELECT * 
FROM tablename
ORDER BY column DESC 
OFFSET 1 ROW 
FETCH NEXT 1 ROW ONLY;
Renato Afonso
źródło
23

Aby uzyskać drugą najwyższą wyraźną wartość w tabeli, możesz użyć

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
źródło
13

Ogólne rozwiązanie może wyglądać jak poniżej:

;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

Tutaj możesz również zdefiniować zakres jak RowNum >= 10 AND RowNum <= 20. I da ci od 10 do 20 wierszy ze wszystkimi wymaganymi kolumnami.

SwapnilBhate
źródło
7

Masz zwykłą najlepszą sztuczkę, taką jak:

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

Możesz także użyć CTE, takich jak:

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

Lub, jeśli używasz najnowszej wersji SQLServer (> = 2012), funkcja lag .

SELECT  top 1  lag(value, 1,0) OVER (ORDER BY value)  
FROM my_table
order by value desc
irimias
źródło
5

Zrobię tak:

SELECT MAX(value)
FROM tablename
WHERE value < (SELECT MAX(value)
               FROM tablename)
Amo
źródło
1

Możesz także użyć ROW_NUMBER()funkcji okienkowania. Jeśli chcesz uzyskać drugi wpis, gdy jest uporządkowany według wartości docelowej, możesz:

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

Teraz, jeśli chcesz uzyskać drugą najwyższą wartość i masz duplikaty, możesz pogrupować według wpisu wartości, aby uzyskać tylko odrębne wartości.

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

Powinieneś być w stanie zmodyfikować to podejście, aby uwzględnić MIN(id)w wewnętrznym zaznaczeniu, jeśli potrzebujesz znać identyfikator pierwszego rekordu z drugą najwyższą wartością (zakładając, że posiadasz zestaw danych z dwoma 60. i dwoma 55.)

CodeMonkey
źródło
5
Na drugi najwyższy łatwiej jest po prostu zastąpić ROW_NUMBER()z DENSE_RANK()- można również uzyskać wszelkie inne kolumny za darmo. Nie musisz używać GROUP BY.
ypercubeᵀᴹ