İkinci en büyük değeri bulmak için en basit SQL Sorgusu nedir?


168

Belirli bir sütundaki ikinci en büyük tamsayı değerini bulmak için en basit SQL sorgusu nedir?

Sütunda yinelenen değerler olabilir.


bu amaç için ofset kullanın ... [dbo] 'dan uzantı seçin. [Çalışanlar] uzantıya göre sipariş desc ofset 2 satır sadece sonraki 1 satırı getirir
Jinto John

Yanıtlar:


295
SELECT MAX( col )
  FROM table
 WHERE col < ( SELECT MAX( col )
                 FROM table )

7
Matt'in yanı sıra Vinoy'un yanıtı kopyaları da halleder. En büyük değerin tekrarlandığını varsayalım, Matt'in cevabını kullanmak doğru ikinci en büyük değeri üretirken, ilk 2 açıklama ve dk yaklaşımını kullanırsanız, bunun yerine en büyük değeri elde edebilirsiniz.
Pankaj Sharma

Ya birden fazla ikinci en yüksek varsa ... O zaman bu tüm Tuples vermeyecek
Parth Satra

2
teşekkür ederim, burada
shaijut

İç açıklama için ORDER_BY ve LIMIT kullanarak yaklaşımımdan çok daha iyi
andig

İstenen kayıttan önce kayıt yoksa bunun bir sonuç döndürmeyeceğini unutmayın.
andig

61
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);

31

T-Sql'de iki yol vardır:

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

Microsoft SQL'de, söz konusu sütun kümelenmiş olsa bile, ilk yol ikincisinin iki katıdır.

Bunun nedeni, sıralama işleminin, maxtoplamanın kullandığı tablo veya dizin taramasına kıyasla nispeten yavaş olmasıdır .

Alternatif olarak, Microsoft SQL 2005 ve sonraki sürümlerde ROW_NUMBER()işlevi kullanabilirsiniz :

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

20

Burada hem SQL Server'a özel hem de MySQL'e özel bazı çözümler görüyorum, bu nedenle hangi veritabanına ihtiyacınız olduğunu netleştirmek isteyebilirsiniz. Eğer tahmin etmek zorunda olsaydım SQL Server diyebilirim, çünkü bu MySQL'de önemsiz.

Ayrıca çalışmayan bazı çözümler de görüyorum çünkü çoğaltma olasılığını dikkate almıyorlar, bu yüzden hangilerini kabul ettiğinize dikkat edin. Son olarak, çalışacak birkaç tane görüyorum, ancak bu tablonun iki tam taramasını yapacak. 2. taramanın sadece 2 değere baktığından emin olmak istiyorsunuz.

SQL Server (2012 öncesi):

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

Güncelleme:

SQL Server 2012 artık çok daha temiz (ve standart ) bir OFFSET / FETCH sözdizimini destekliyor :

SELECT TOP 2 [column] 
FROM [Table] 
GROUP BY [column] 
ORDER BY [column] DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;

Bunu görmeyi umuyordum. Herhangi biri için çalışmanız gerekiyorsa, kabul edilen cevap çirkinleşir n. Bu test duruyor.
Robin Maben

@RobinMaben Robin, en büyük değer tekrarlandığında senaryoya ne dersiniz? Bir sütunun 1'den 100'e kadar sayılar içerdiğini ancak 100'ün iki kez tekrarlandığını varsayalım. Daha sonra bu çözüm 100 olarak ikinci en büyük değeri üretecek ve bu yanlış olacaktır. Sağ?
Pankaj Sharma

1
@PankajSharma no, GROUP BY yan tümcesi nedeniyle bu hala işe yarayacak
Joel Coehoorn

Bunu yapmanın standart yolu budur. Kabul edilen cevap bu cevapla güncellenmelidir.
Guilherme Melo

1
Ben kullanamam diye bir hata alıyorum TOPve OFFSETaynı sorguda.
Sahte

15

Sanırım şöyle bir şey yapabilirsiniz:

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

veya

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

veritabanı sunucunuza bağlı olarak. İpucu: SQL Server LIMIT yapmaz.


update- SQL Server 2012, yukarıdaki dbadiaries.com/… 'a
iliketocode

Aynı değere sahip ancak aynı zamanda en büyük öğeye sahip 2 öğeniz olduğunu varsayalım. Sanırım yapmanız gerekiyorOFFSET 2
Kangkan

GROUP BY deyimi eklenmesi, buradaki yinelenen koşulu karşılar.
Saif

7

En kolayı, uygulamada bu sonuç kümesinden ikinci değeri elde etmek olacaktır:

SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2

Ancak SQL kullanarak ikinci değeri seçmeniz gerekiyorsa, nasıl olur:

SELECT MIN(value) FROM (SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2) AS t

1
Bunu SQL Server'da çalıştırdınız mı?
Craig

1
@Craig - LIMITMySql sözdizimidir, soru bir SQL sürümü belirtmez.
Keith


4

İkinci en büyük değeri bulmak için çok basit bir sorgu

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

Alt sorgulara gerek yok ... sadece bir satırı atlayın ve siparişten sonra azalan ikinci satırları seçin


3
SELECT MAX(Salary) FROM Employee WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee )

Bu sorgu, genel tablodan maksimum maaş içermeyen sonuçtan maksimum maaş döndürür.


2
Bunun eski cevaplardan ne kadar farklı olduğunu açıklamak için düzenleyebilir misiniz ?
Nathan Tuggy

3

Biliyorum eski soru, ama bu bana daha iyi bir yürütme planı verdi:

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

3

Bu çok basit bir kod, bunu deneyebilirsiniz: -

ör .: Tablo adı = test

salary 

1000
1500
1450
7500

MSSQL Kodu en yüksek 2. değeri elde etmek için

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

burada '1 satır öteleme' tablonun 2. satırı anlamına gelir ve 'yalnızca sonraki 1 satırı getir' yalnızca 1 satırı göstermek içindir. 'yalnızca sonraki 1 satırı getir' seçeneğini kullanmazsanız, ikinci satırdaki tüm satırları gösterir.


En optimize ve Kaynak dostu Cevap. Alt sorgularımda oldukça fazla zaman kazandım. Teşekkürler.
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

Herhangi bir satır için değer almak için bu yardım umuyoruz .....


2

Hepsinden basit

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)

Not

sal col adı
emp olduğunu tablo adı


1

Tom, inan, birden fazla değer döndürüldüğünde bunun başarısız olacağını düşün. select max([COLUMN_NAME]) from [TABLE_NAME] bölümde . yani veri kümesinde 2'den fazla değer olduğunda.

Sorgunuzda hafif bir değişiklik yapılacak -

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

alt sorgu, en büyük değer dışındaki tüm değerleri döndürür. döndürülen listeden maksimum değeri seçin.


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

Bu en kolay yoldur:

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

Bahsettiğiniz gibi yinelenen değerler. Bu durumda DISTINCT ve GROUP BY kullanarak ikinci en yüksek değeri bulabilirsiniz

İşte bir tablo

maaş

:

resim açıklamasını buraya girin

GRUPLA

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

DISTINCT

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

LIMIT'in ilk kısmı = başlangıç ​​endeksi

LIMIT'in ikinci kısmı = kaç değer


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

bu emp tablosunun üçüncü en yüksek tuzunu döndürür


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

değil , sütun_adı en yüksek değerini hariç tutan bir koşuldur.

Referans: programcı röportajı


0

Böyle bir şey mi? Yine de test etmedim:

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


0

İlişkili bir sorgu kullanma:

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)

Bu sorgu en fazla üç maaş seçer. İki emp aynı maaşı alırsanız, bu sorgu etkilemez.


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

0

Bu MS SQL'de çalışır:

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] < 
 ( select max([COLUMN_NAME]) from [TABLE_NAME] )
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.