2番目に大きい値を見つけるための最も単純なSQLクエリは何ですか?


168

特定の列で2番目に大きい整数値を見つける最も簡単なSQLクエリは何ですか?

列に重複した値がある可能性があります。


この目的のためにオフセットを使用... [dbo]から拡張を選択します。[従業員]拡張による順序descオフセット2行は次の1行のみフェッチ
Jinto John

回答:


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

7
マットとビノイの答えは、重複も処理します。最大値が繰り返されている場合、Mattの回答を使用すると2番目に大きい正しい値が生成されますが、上位2つのdescおよびminアプローチを使用した場合は、代わりに最大値を取得できます。
Pankaj Sharma

2番目に高いものが複数ある場合はどうなりますか?次に、これはすべてのタプルを提供しません
Parth Satra

2
ありがとう、これを使用してここで
shaijut

内部ステートメントにORDER_BYとLIMITを使用する私のアプローチよりもはるかに良い
andig

リクエストされたレコードの前にレコードがない場合、これは結果を返さないことに注意してください。
andig


31

T-SQLには2つの方法があります。

--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では、問題の列がクラスター化されている場合でも、最初の方法は2番目の方法の2倍高速です。

これは、max集計が使用するテーブルまたはインデックススキャンと比較して、ソート操作が比較的遅いためです。

または、Microsoft SQL 2005以降では、次のROW_NUMBER()関数を使用できます。

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

20

ここでは、SQL Server固有のソリューションとMySQL固有のソリューションの両方を確認しているので、必要なデータベースを明確にしたいと思うかもしれません。私が推測しなければならないのであれば、これはMySQLでは些細なことなのでSQLサーバーと言います。

また、重複の可能性を考慮に入れていないため機能しないソリューションもいくつかあるので、どのソリューションを受け入れるか注意してください。最後に、いくつかは機能しますが、テーブルの2つの完全なスキャンが行われます。2番目のスキャンが2つの値のみを確認していることを確認します。

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

更新:

SQL Server 2012では、よりクリーンな(および標準の)OFFSET / FETCH構文がサポートされるようになりました。

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

これは私が見たかったものです。受け入れられた答えは、もしあなたが何かのために働く必要があるならば、醜くなりますn。これはそのテストに耐えます。
Robin Maben

@RobinMaben Robin、最大値が繰り返されるシナリオはどうですか?列に1から100までの数字が含まれているが、100が2回繰り返されているとします。次に、このソリューションは2番目に大きい値を100として生成しますが、これは正しくありません。正しい?
Pankaj Sharma

1
@PankajSharmaいいえ、GROUP BY句のため、これは引き続き機能します
Joel Coehoorn 2013

これは、これを行うための標準的な方法です。受け入れられた回答はこれに更新する必要があります。
Guilherme Melo

1
私は、私が使用することはできませんというエラーを取得TOPし、OFFSET同じクエリ内を。
スプリアス、2015年

15

私はあなたが次のようなことをすることができると思います:

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

または

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

データベースサーバーによって異なります。ヒント:SQL ServerはLIMITを実行しません。


update- SQL Server 2012は、上記のdbadiaries.com/…
iliketocode

同じ値を持つ2つの要素があり、最大の要素もあるとします。私はあなたがしなければならないことを推測しますOFFSET 2
カンカン

GROUP BY句を追加すると、重複した条件に対応できます。
Saif

7

最も簡単なのは、アプリケーションのこの結果セットから2番目の値を取得することです。

SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2

しかし、SQLを使用して2番目の値を選択する必要がある場合は、次のようにします。

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

1
これをSQL Serverで実行しましたか?
クレイグ

1
@Craig- LIMITMySql構文です。質問はSQLバージョンを指定しません。
キース

7

次のクエリを使用して、列の2番目に大きい値を見つけることができます

SELECT *
FROM TableName a
WHERE
  2 = (SELECT count(DISTINCT(b.ColumnName))
       FROM TableName b WHERE
       a.ColumnName <= b.ColumnName);

あなたは次のリンクで詳細を見つけることができます

http://www.abhishekbpatel.com/2012/12/how-to-get-nth-maximum-and-minimun.html


デッドリンクのアーカイブ:web.archive.org/web/20130406161645/http
//…

4

2番目に大きい値を見つける非常に単純なクエリ

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

サブクエリの必要はありません... 1行をスキップし、降順で順序の後に2行目を選択します


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

このクエリは結果から最大給与を返します-これにはテーブル全体の最大給与は含まれていません。


2
これが以前の回答と大きく異なる点を説明するために編集できますか?
Nathan Tuggy、2015年

3

私の知っている古い質問ですが、これは私により良い執行計画を与えました:

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

3

これは非常に単純なコードです。これを試すことができます:-

例:テーブル名= test

salary 

1000
1500
1450
7500

2番目に大きい値を取得するMSSQLコード

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

ここで「オフセット1行」とはテーブルの2行目を意味し、「次の1行のみフェッチ」はその1行のみを表示するためのものです。「次の1行のみフェッチ」を使用しない場合は、2行目のすべての行が表示されます。


最も最適化されたリソースフレンドリーな回答。サブクエリで使用することで、かなりの時間を節約できました。ありがとう。
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

これが任意の行の値を取得するのに役立つことを願っています.....


2

最も単純な

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)

注意

salはcol名、
empはテーブル名


1

トム、返された値が複数あると失敗する select max([COLUMN_NAME]) from [TABLE_NAME]セクションで。つまり、データセットに2つ以上の値がある場合です。

クエリを少し変更すると機能します-

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

サブクエリは、最大値以外のすべての値を返します。返されたリストから最大値を選択します。


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

あなたが重複した値を述べたように。そのような場合、DISTINCTGROUP BYを使用して2番目に高い値を見つけることができます

こちらが表です

給料

ここに画像の説明を入力してください

GROUP BY

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

明確な

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

LIMITの最初の部分=開始インデックス

LIMITの2番目の部分=値の数


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

これは、empテーブルの3番目に高いsalを返します



0

このようなもの?しかし、私はそれをテストしていません:

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


0

相関クエリを使用する:

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)

このクエリは、最大3つの給与を選択します。2人の従業員が同じ給与を取得しても、クエリには影響しません。


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

0

これはMS SQLで機能します。

select max([COLUMN_NAME]) from [TABLE_NAME] where [COLUMN_NAME] < 
 ( select max([COLUMN_NAME]) from [TABLE_NAME] )
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.