두 번째로 큰 값을 찾는 가장 간단한 SQL 쿼리는 무엇입니까?


168

특정 열에서 두 번째로 큰 정수 값을 찾는 가장 간단한 SQL 쿼리는 무엇입니까?

열에 중복 값이있을 수 있습니다.


.이 목적의 ... [DBO]로부터 선택 연장 오프셋을 [종업원] 연장하여 내림차순 순서 2 행 다음의 1 개 행을 페치 만 오프셋
Jinto 존

답변:


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

7
매트와 Vinoy의 답변은 복제본도 처리합니다. 가장 큰 값이 반복되었다고 가정하고 Matt의 대답을 사용하면 올바른 두 번째로 큰 값을 생성하지만 상위 2 descmin 접근 방식을 사용하면 가장 큰 값을 얻을 수 있습니다.
Pankaj Sharma

몇 초 만에 최고라면 ... 그러면 이것은 모든 튜플을 제공하지는 않습니다
Parth Satra

2
감사합니다. 여기에서
shaijut

내부 진술에 ORDER_BY와 LIMIT를 사용하는 나의 접근 방식보다 훨씬 낫습니다
andig

요청 된 레코드 이전에 레코드가없는 경우 결과가 리턴되지 않습니다.
andig

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

31

T-Sql에는 두 가지 방법이 있습니다.

--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에서 첫 번째 방법은 해당 열이 클러스터되어 있어도 두 번째 방법보다 두 배 빠릅니다.

정렬 작업이 테이블 또는 인덱스 스캔에 비해 상대적으로 느리기 때문입니다. 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 고유 솔루션이 모두 있으므로 필요한 데이터베이스를 명확히하고 싶을 수도 있습니다. 내가 추측해야한다면 SQL Server는 MySQL에서 사소하기 때문에 말할 것입니다.

또한 중복 가능성을 고려하지 않아 작동하지 않는 일부 솔루션을 보았으므로 어떤 솔루션을 수락할지주의하십시오. 마지막으로, 몇 가지 작동하지만 테이블을 두 번 완전히 스캔하는 것을 볼 수 있습니다. 두 번째 스캔이 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이 두 번 반복된다고 가정하십시오. 그런 다음이 솔루션은 두 번째로 큰 값을 100으로 생성하므로 올바르지 않습니다. 권리?
Pankaj Sharma

1
@PankajSharma 아니오, 이것은 GROUP BY 조항 때문에 여전히 작동합니다
Joel Coehoorn

이것이 표준 방법입니다. 수락 된 답변은이 답변으로 업데이트되어야합니다.
Guilherme Melo

1
내가 사용할 수 없다는 오류 수 TOPOFFSET같은 쿼리를.
Spurious

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
Kangkan

GROUP BY 절을 추가하면 이에 중복 조건이 적용됩니다.
Saif

7

가장 쉬운 방법은 응용 프로그램의이 결과 집합에서 두 번째 값을 얻는 것입니다.

SELECT DISTINCT value FROM Table ORDER BY value DESC LIMIT 2

그러나 SQL을 사용하여 두 번째 값을 선택 해야하는 경우 어떻습니까?

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

1
SQL Server에서 이것을 실행 했습니까?
Craig

1
@Craig- LIMITMySql 구문이며 질문에 SQL 버전이 지정되어 있지 않습니다.
Keith


4

두 번째로 큰 값을 찾기위한 매우 간단한 쿼리

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

하위 쿼리가 필요하지 않습니다 ... 한 행을 건너 뛰고 내림차순으로 주문 후 두 번째 행을 선택하십시오.


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

이 쿼리는 전체 테이블의 최대 급여를 포함하지 않는 결과에서 최대 급여를 반환합니다.


2
이것이 이전 답변과 크게 다른 점을 설명하기 위해 편집 할 수 있습니까 ?
Nathan Tuggy

3

내가 알고있는 오래된 질문이지만, 이것은 나에게 더 나은 exec 계획을 주었다.

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

3

이것은 매우 간단한 코드입니다.

예 : 테이블 이름 = 테스트

salary 

1000
1500
1450
7500

두 번째로 큰 가치를 얻는 MSSQL 코드

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

여기서 'offset 1 rows'는 테이블의 두 번째 행을 의미하며 '다음 1 행만 가져 오기'는 해당 1 행만 표시하기위한 것입니다. '다음 1 행만 가져 오기'를 사용하지 않으면 두 번째 행의 모든 ​​행이 표시됩니다.


가장 최적화되고 리소스 친화적 인 답변. 하위 쿼리에서이를 사용하여 많은 시간을 절약했습니다. 감사.
vibs2006 10

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 name입니다
.emp는 테이블 이름입니다.


1

톰, 둘 이상의 값이 반환되면 실패 할 것이라고 믿습니다. select max([COLUMN_NAME]) from [TABLE_NAME] 섹션에 . 즉, 데이터 세트에 3 개 이상의 값이있는 경우.

검색어를 약간 수정하면 효과가 있습니다.

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

가장 현명한 방법입니다.

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

중복 값을 언급했듯이. 이 경우 DISTINCTGROUP BY를 사용할 수 있습니다 를 하여 두 번째로 높은 값을 찾을 수 있습니다

여기 테이블이 있습니다

봉급

:

여기에 이미지 설명을 입력하십시오

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의 두 번째 부분 = 값의 수


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

이것은 emp 테이블의 세 번째로 높은 sal을 반환합니다


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

에 없다 은 column_name의 가장 높은 값을 제외하는 조건입니다.

참조 : 프로그래머 인터뷰


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 개의 급여를 선택합니다. 두 개의 emp가 동일한 급여를받는 경우 쿼리에 영향을 미치지 않습니다.


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.