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?
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:
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;
Để 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);
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.
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
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)
ROW_NUMBER()
bằngDENSE_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ụngGROUP BY
.