Який найпростіший запит SQL знайти друге за величиною значення?


168

Який найпростіший запит SQL для пошуку другого за величиною цілого значення в конкретному стовпчику?

У стовпчику можуть бути дублюючі значення.


використовуйте зсув для цієї мети ... виберіть розширення з [dbo]. [Співробітники] замовлення за розширенням зсуву 2 рядки отримують лише наступні 1 рядки
Jinto John

Відповіді:


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

7
Відповідь Метта, а також відповіді Віноя також піклується про дублікати. Припустимо, що найбільше значення повторюється, тоді за допомогою відповіді Метта вийде правильне друге за величиною значення, тоді як якщо ви використовуєте підхід 2 та 10 хв. , Ви можете отримати найбільше значення.
Pankaj Sharma

Що робити, якщо є кілька секунд найвищих ... Тоді це не дасть усім кортежів
Parth Satra

2
дякую, використав це для пошуку другої останньої дати тут
shaijut

Набагато краще, ніж мій підхід із використанням ORDER_BY та LIMIT для внутрішнього висловлювання
andig

Зверніть увагу, що результат не поверне, якщо до запиту не буде записів.
andig


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-е сканування дивиться лише на 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. Цей - це тест.
Робін Мабен

@RobinMaben Робін, як щодо сценарію, коли найбільше значення повторюється? Припустимо, стовпець містить числа від 1 до 100, але 100 повторюється двічі. Тоді це рішення дасть друге за величиною значення 100, що буде неправильним. Правильно?
Pankaj Sharma

1
@PankajSharma ні, це все одно спрацює через пункт GROUP BY
Joel Coehoorn,

Це стандартний спосіб зробити це. Прийняту відповідь слід оновити до цієї.
Guilherme Melo

1
Я отримую помилку, яка говорить, що я не можу використовувати TOPі OFFSETв тому самому запиті.
Грізний

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 забезпечить повторювану умову в цьому.
Сайф

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?
Крейг

1
@Craig - LIMITце синтаксис MySql, питання не визначає версію SQL.
Кіт

7

ви можете знайти друге за величиною значення стовпця, скориставшись наступним запитом

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://…
xgMz

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
Чи можете ви редагувати, щоб пояснити, чим це суттєво відрізняється від старих відповідей?
Натан Туггі

3

Я знаю старе питання, але це дало мені кращий план виконання:

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

3

Це дуже простий код, ви можете спробувати це: -

напр .: Назва таблиці = тест

salary 

1000
1500
1450
7500

Код MSSQL, щоб отримати 2-е за величиною значення

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

тут "зміщення 1 рядка" означає 2-й рядок таблиці, а "отримати лише наступні 1 рядок" - для показу лише той 1 рядок. якщо ви не використовуєте "отримати лише наступні 1 рядок", він відображає всі рядки з другого ряду.


Найбільш оптимізований та ресурс-відповідь. Я заощадив досить багато часу, використовуючи його у своєму підзапиті. Дякую.
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]розділі повернеться більше одного значення . тобто там, де в наборі даних більше двох значень.

Незначна модифікація вашого запиту спрацює -

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

Як ви згадали дублюючі значення. У такому випадку ви можете використовувати DISTINCT та 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 )

це поверне третю найвищу позицію таблиці



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)

Цей запит вибирає максимум три зарплати. Якщо двоє працівників отримують однакову зарплату, це не впливає на запит.


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] )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.