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.


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 )

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

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

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;

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.


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

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;

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


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.


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

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.


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


2

Yang paling sederhana

select sal from salary order by sal desc limit 1 offset 1

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


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

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.


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

1
SELECT 
    * 
FROM 
    table 
WHERE 
    column < (SELECT max(columnq) FROM table) 
ORDER BY 
    column DESC LIMIT 1

1

Ini adalah cara yang paling sulit:

SELECT
      Column name
FROM
      Table name 
ORDER BY 
      Column name DESC
LIMIT 1,1

1
select age from student group by id having age<(select max(age) from student)order by age limit 1

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


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


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


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


0

Menggunakan kueri yang berkorelasi:

Select * from x x1 where 1 = (select count(*) from x where x1.a < a)

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.


0
select top 1 MyIntColumn from MyTable
where
 MyIntColumn <> (select top 1 MyIntColumn from MyTable order by MyIntColumn desc)
order by MyIntColumn desc

0

Ini bekerja di MS SQL:

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] < 
 ( select max([COLUMN_NAME]) from [TABLE_NAME] )
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.