Apa SQL Query paling sederhana untuk menemukan nilai terbesar kedua?

168

Apa permintaan SQL paling sederhana untuk menemukan nilai integer terbesar kedua di kolom tertentu?

Mungkin ada nilai duplikat di kolom.

Niyaz
sumber
gunakan offset untuk tujuan ini ... pilih ekstensi dari [dbo]. [Karyawan] pesan dengan ekstensi, hapus, offset, 2 baris, ambil hanya 1 baris berikutnya
Jinto John

Jawaban:

294
SELECT MAX( col )
  FROM table
 WHERE col < ( SELECT MAX( col )
                 FROM table )
Matt Rogish
sumber
7
Jawaban Matt dan Vinoy juga menangani duplikat. Misalkan nilai terbesar diulang maka menggunakan jawaban Matt akan menghasilkan nilai terbesar kedua yang benar sementara jika Anda menggunakan pendekatan 2 desc dan min teratas , Anda mungkin mendapatkan nilai terbesar sebagai gantinya.
Pankaj Sharma
Bagaimana jika ada beberapa tertinggi kedua ... Maka ini tidak akan memberikan semua Tuples
Parth Satra
2
terima kasih, gunakan ini untuk mencari kencan terakhir kedua di sini
shaijut
Jauh lebih baik daripada pendekatan saya menggunakan ORDER_BY dan LIMIT untuk pernyataan bagian dalam
andig
Catatan ini tidak akan mengembalikan hasil jika tidak ada catatan sebelum yang diminta.
andig
61
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);
Vinoy
sumber
31

Dalam T-Sql ada dua cara:

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

Dalam Microsoft SQL cara pertama dua kali lebih cepat daripada yang kedua, bahkan jika kolom tersebut berkerumun.

Ini karena operasi pengurutan relatif lambat dibandingkan dengan pemindaian tabel atau indeks yang maxdigunakan agregasi.

Atau, di Microsoft SQL 2005 dan di atas Anda dapat menggunakan ROW_NUMBER()fungsi:

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

Saya melihat beberapa SQL Server khusus dan beberapa solusi spesifik MySQL di sini, jadi Anda mungkin ingin memperjelas database yang Anda butuhkan. Padahal jika saya harus menebak saya akan mengatakan SQL Server karena ini sepele di MySQL.

Saya juga melihat beberapa solusi yang tidak akan berhasil karena gagal memperhitungkan kemungkinan duplikat, jadi berhati-hatilah mana yang Anda terima. Akhirnya, saya melihat beberapa yang akan bekerja tetapi itu akan membuat dua scan lengkap tabel. Anda ingin memastikan pemindaian ke-2 hanya melihat 2 nilai.

SQL Server (pra-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

Memperbarui:

SQL Server 2012 sekarang mendukung sintaks OFFSET / FETCH yang jauh lebih bersih (dan standar ):

SELECT TOP 2 [column] 
FROM [Table] 
GROUP BY [column] 
ORDER BY [column] DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;
Joel Coehoorn
sumber
Inilah yang saya harapkan untuk dilihat. Jawaban yang diterima ternyata jelek jika Anda membutuhkannya n. Yang ini tahan uji itu.
Robin Maben
@RobinMaben Robin, bagaimana dengan skenario ketika nilai terbesar diulang? Misalkan kolom berisi angka 1 hingga 100 tetapi 100 diulang dua kali. Maka solusi ini akan menghasilkan nilai terbesar kedua sebagai 100, yang akan salah. Baik?
Pankaj Sharma
1
@PankajSharma tidak, ini masih akan bekerja, karena klausa GROUP BY
Joel Coehoorn
Ini adalah cara standar untuk melakukan ini. Jawaban yang diterima harus diperbarui untuk yang satu ini.
Guilherme Melo
1
Saya mendapatkan kesalahan yang mengatakan saya tidak bisa menggunakan TOPdan OFFSETdalam permintaan yang sama.
Spurious
15

Saya kira Anda dapat melakukan sesuatu seperti:

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

atau

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

tergantung pada server database Anda. Petunjuk: SQL Server tidak melakukan LIMIT.

dguaraglia
sumber
update- SQL Server 2012 menambahkan klausa offset / pengambilan yang mirip dengan dbadiaries.com/...
iliketocode
Misalkan Anda memiliki 2 elemen dengan nilai yang sama tetapi juga elemen terbesar. Saya kira Anda harus melakukanOFFSET 2
Kangkan
Menambahkan klausa GROUP BY akan memenuhi kondisi duplikat dalam hal ini.
Saif
7

Cara termudah adalah mendapatkan nilai kedua dari hasil yang ditetapkan di aplikasi ini:

SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2

Tetapi jika Anda harus memilih nilai kedua menggunakan SQL, bagaimana dengan:

SELECT MIN(value) FROM (SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2) AS t
Magnar
sumber
1
Sudahkah Anda menjalankan ini di SQL Server?
Craig
1
@Craig - LIMITadalah sintaks MySql, pertanyaannya tidak menentukan versi SQL.
Keith
4

Permintaan yang sangat sederhana untuk menemukan nilai terbesar kedua

SELECT `Column` FROM `Table` ORDER BY `Column` DESC LIMIT 1,1;
petcy
sumber
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

Tidak perlu sub kueri ... lewati satu baris dan pilih baris kedua setelah pesanan dengan menurun

Justin Jose
sumber
3
SELECT MAX(Salary) FROM Employee WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee )

Permintaan ini akan mengembalikan gaji maksimum, dari hasil - yang tidak mengandung gaji maksimum dari keseluruhan tabel.

Naresh Kumar
sumber
2
Dapatkah Anda mengedit untuk menjelaskan bagaimana ini sangat berbeda dari jawaban yang lama?
Nathan Tuggy
3

Pertanyaan lama yang saya tahu, tetapi ini memberi saya rencana eksekutif yang lebih baik:

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

Ini adalah kode yang sangat sederhana, Anda dapat mencoba ini: -

mis: Nama tabel = tes

salary 

1000
1500
1450
7500

Kode MSSQL untuk mendapatkan nilai terbesar ke-2

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

di sini 'offset 1 baris' berarti baris ke-2 tabel dan 'ambil 1 baris berikutnya saja' hanya untuk menunjukkan 1 baris. jika Anda tidak menggunakan 'ambil hanya 1 baris berikutnya' maka ini akan menampilkan semua baris dari baris kedua.

Nijish.
sumber
Jawaban yang paling optimal dan ramah sumber daya. Saya menghemat banyak waktu menggunakannya di subquery saya. Terima kasih.
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

Semoga bantuan ini mendapatkan nilai untuk setiap baris .....

Rohit Singh
sumber
2

Yang paling sederhana

select sal from salary order by sal desc limit 1 offset 1
sumeet
sumber
1
select min(sal) from emp where sal in 
    (select TOP 2 (sal) from emp order by sal desc)

Catatan

sal is col nama
emp adalah nama tabel

Ni3
sumber
1

Tom, yakin ini akan gagal ketika ada lebih dari satu nilai yang dikembalikan di select max([COLUMN_NAME]) from [TABLE_NAME]bagian. yaitu di mana ada lebih dari 2 nilai dalam kumpulan data.

Modifikasi sedikit ke kueri Anda akan bekerja -

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] **IN** 
  ( select max([COLUMN_NAME]) from [TABLE_NAME] )
sunith
sumber
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));

subquery mengembalikan semua nilai selain yang terbesar. pilih nilai maksimal dari daftar yang dikembalikan.

sunith
sumber
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
Divya.NR
sumber
1
SELECT 
    * 
FROM 
    table 
WHERE 
    column < (SELECT max(columnq) FROM table) 
ORDER BY 
    column DESC LIMIT 1
burung pipit avie
sumber
1

Ini adalah cara yang paling sulit:

SELECT
      Column name
FROM
      Table name 
ORDER BY 
      Column name DESC
LIMIT 1,1
Ravind Maurya
sumber
1
select age from student group by id having age<(select max(age) from student)order by age limit 1
JALAN BUNTU
sumber
1

Seperti yang Anda sebutkan nilai duplikat. Dalam hal demikian, Anda dapat menggunakan DISTINCT dan GROUP BY untuk mengetahui nilai tertinggi kedua

Ini meja

gaji

:

masukkan deskripsi gambar di sini

KELOMPOK OLEH

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

BERBEDA

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

Bagian pertama LIMIT = indeks awal

Bagian kedua LIMIT = berapa nilai

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

ini akan mengembalikan sal tabel emp tertinggi ketiga

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

not in adalah kondisi yang mengecualikan nilai tertinggi dari nama_kolom.

Referensi: wawancara programmer

ruam
sumber
0

Sesuatu seperti ini? Saya belum mengujinya:

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

Menggunakan kueri yang berkorelasi:

Select * from x x1 where 1 = (select count(*) from x where x1.a < a)
sth
sumber
0
select * from emp e where 3>=(select count(distinct salary)
    from emp where s.salary<=salary)

Permintaan ini memilih maksimum tiga gaji. Jika dua emp mendapatkan gaji yang sama ini tidak mempengaruhi permintaan.

sth
sumber
0
select top 1 MyIntColumn from MyTable
where
 MyIntColumn <> (select top 1 MyIntColumn from MyTable order by MyIntColumn desc)
order by MyIntColumn desc
Chris Conway
sumber
0

Ini bekerja di MS SQL:

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] < 
 ( select max([COLUMN_NAME]) from [TABLE_NAME] )
Tom Welch
sumber