Nhận giá trị cao thứ hai trong một bảng


14
id value
1   50
2   60
3   55

select max(value) from tablename;

Nói chung chúng tôi biết, chúng tôi sẽ nhận được 60, nhưng tôi cần giá trị tiếp theo 55.

Làm cách nào để tôi nhận được giá trị 55 bằng SQL?

Câu trả lời:


24

Giả sử giá trị cao nhất chỉ xảy ra một lần, một cách khác sẽ được sử dụng OFFSET(SQL Server 2012 trở lên):

SELECT * 
FROM tablename
ORDER BY column DESC 
OFFSET 1 ROW 
FETCH NEXT 1 ROW ONLY;

24

Để có được giá trị khác biệt cao thứ hai trong bảng, bạn có thể sử dụng

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);

13

Một giải pháp chung có thể như dưới đây:

;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

Ở đây bạn cũng có thể định nghĩa phạm vi như thế nào RowNum >= 10 AND RowNum <= 20. Và nó sẽ cung cấp cho bạn hàng thứ 10 đến 20 với tất cả các cột bắt buộc.


7

Bạn có thủ thuật hàng đầu thông thường như:

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

Hoặc bạn cũng có thể sử dụng CTE như:

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

Hoặc, nếu bạn sử dụng phiên bản gần đây của SQLServer (> = 2012), hàm lag .

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

5

Tôi sẽ làm như thế này:

SELECT MAX(value)
FROM tablename
WHERE value < (SELECT MAX(value)
               FROM tablename)

1

Bạn có thể sử dụng ROW_NUMBER()chức năng cửa sổ là tốt. Nếu bạn muốn có mục nhập thứ 2 khi được sắp xếp theo giá trị mục tiêu của mình, bạn có thể làm:

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

Bây giờ nếu bạn muốn nhận giá trị cao thứ 2 và bạn có các bản sao, bạn có thể muốn nhóm theo mục nhập giá trị để bạn chỉ nhận được các giá trị riêng biệt.

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

Bạn sẽ có thể sửa đổi cách tiếp cận này để đưa MIN(id)vào lựa chọn bên trong nếu bạn cần biết ID của bản ghi đầu tiên với giá trị cao thứ 2 (giả sử bạn có một bộ dữ liệu có hai 60 và hai 55)


5
Đối với mức cao thứ hai, việc thay thế ROW_NUMBER()bằng DENSE_RANK()- bạn cũng có được tất cả các cột khác miễn phí. Không cần sử dụng GROUP BY.
ypercubeᵀᴹ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.