Выберите n-я строка, используя условие в базе данных оракула [duplicate]

Если вы, к сожалению, не используете .NET4:

string.Format("{0}h{1}m{2}s",
    myTimeSpan.Hours,
    myTimeSpan.Minutes,
    myTimeSpan.Seconds);
321
задан Community 23 May 2017 в 12:34
поделиться

28 ответов

Есть способы сделать это в необязательных частях стандарта, но многие базы данных поддерживают их собственный способ сделать это.

Действительно хороший сайт, который говорит об этом и других вещах, - http://troels.arvin.dk/db/rdbms/#select-limit .

В принципе, PostgreSQL и MySQL поддерживают нестандартные:

SELECT...
LIMIT y OFFSET x 

Oracle, DB2 и MSSQL поддерживают стандартные функции окон:

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
) AS foo
WHERE rownumber <= n

(которые я только что скопировал с сайта, связанного выше, так как я никогда не использую эти БД)

Обновление: Начиная с PostgreSQL 8.4 поддерживаются стандартные функции оконной обработки, поэтому ожидаем, что второй пример будет работать и для PostgreSQL.

283
ответ дан Chris 15 August 2018 в 20:30
поделиться
  • 1
    MySQL также использует синтаксис OFFSET и LIMIT. Firebird использует ключевые слова FIRST и SKIP, но они размещаются сразу после SELECT. – Doug 1 December 2011 в 19:03
  • 2
    Разве это не должно быть WHERE rownumber = n для получения только n-й строки? – Steve Bennett 12 September 2017 в 07:14
SELECT * FROM emp a
WHERE  n = (SELECT COUNT( _rowid)
              FROM emp b
             WHERE a. _rowid >= b. _rowid);
1
ответ дан 2 revs, 2 users 62%Rahul Sharma 15 August 2018 в 20:30
поделиться

Когда мы работали в MSSQL 2000, мы сделали то, что мы назвали «triple-flip»:

EDITED

DECLARE @InnerPageSize int
DECLARE @OuterPageSize int
DECLARE @Count int

SELECT @Count = COUNT(<column>) FROM <TABLE>
SET @InnerPageSize = @PageNum * @PageSize
SET @OuterPageSize = @Count - ((@PageNum - 1) * @PageSize)

IF (@OuterPageSize < 0)
    SET @OuterPageSize = 0
ELSE IF (@OuterPageSize > @PageSize)
    SET @OuterPageSize = @PageSize

DECLARE @sql NVARCHAR(8000)

SET @sql = 'SELECT * FROM
(
    SELECT TOP ' + CAST(@OuterPageSize AS nvarchar(5)) + ' * FROM
    (
        SELECT TOP ' + CAST(@InnerPageSize AS nvarchar(5)) + ' * FROM <TABLE> ORDER BY <column> ASC
    ) AS t1 ORDER BY <column> DESC
) AS t2 ORDER BY <column> ASC'

PRINT @sql
EXECUTE sp_executesql @sql

Это было не изящно, и это был не быстрым, но он работал.

6
ответ дан Adam V 15 August 2018 в 20:30
поделиться
  • 1
    Скажем, у вас есть 25 строк, и вам нужна третья страница из 10 строк в строке, то есть строки 21-25. Самый внутренний запрос получает верхние 30 строк (строки 1-25). Средний запрос получает последние 10 строк (строки 25-16). Внешний запрос переупорядочивает их и возвращает строки 16-25. Это явно неправильно, если вам нужны строки 21-25. – Bill Karwin 30 December 2011 в 10:53
  • 2
    Теперь это не работает, если нам нужна средняя страница. Скажем, у нас есть 25 строк, и нам нужна вторая страница, то есть строки 11-20. Внутренний запрос получает верхние 2 * 10 = 20 строк или строки 1-20. Средний запрос получает последние 15 строк: 25 - ((2-1) * 10) = 15, что дает строки 20-6. Последний запрос меняет порядок и возвращает строки 6-20. Этот метод не работает, если общее количество строк не кратно вашему желаемому размеру страницы. – Bill Karwin 30 December 2011 в 19:14
  • 3
    Возможно, лучший вывод заключается в том, что мы должны обновить все оставшиеся экземпляры MS SQL Server 2000. :-) Это почти 2012 год, и эта проблема была решена лучшими способами на протяжении многих лет! – Bill Karwin 30 December 2011 в 19:15
  • 4
    @Bill Karwin: Обратите внимание на блоки IF / ELSE IF ниже вычисления OuterPageSize - на страницах 1 и 2 они вернут значение OuterPageSize до 10. На странице 3 (строки 21-25) расчет будет правильно возвращать 5 , а на всех страницах 4 и выше отрицательный результат вычисления будет заменен на 0 (хотя, вероятно, просто быстрее будет сразу возвращать пустую строку данных в этой точке). – Adam V 1 January 2012 в 03:50
  • 5
    Теперь я вижу. Ну, я полагаю, что использование MS SQL Server 2000 сегодня не стоит проблем. – Bill Karwin 1 January 2012 в 04:57

SQL SERVER


Выберите n'th запись сверху

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

выберите n-ю запись снизу

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n
6
ответ дан Aditya 15 August 2018 в 20:30
поделиться

Вот быстрое решение вашей путаницы.

SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1

Здесь вы можете получить последнюю строку, заполняя N = 0, второе последним - N = 1, четвертое последнее заполнение N = 3 и так далее на.

Это очень распространенный вопрос в интервью, и это очень простые его аспекты.

Далее Если вы хотите, чтобы сумма, идентификатор или некоторый числовой порядок сортировки, чем у, могли идти для функции CAST в MySQL.

SELECT DISTINCT (`amount`) FROM cart ORDER BY CAST( `amount` AS SIGNED ) DESC LIMIT 4 , 1

Здесь, заполнив N = 4, вы сможете получить пятый последний рекорд наибольшей суммы из таблицы CART. Вы можете поместить свое имя поля и таблицы и придумать решение.

3
ответ дан Amit Shah 15 August 2018 в 20:30
поделиться

ADD:

LIMIT n,1

Это ограничит результаты одним результатом, начиная с результата n.

2
ответ дан Andrew G. Johnson 15 August 2018 в 20:30
поделиться
select * from 
(select * from ordered order by order_id limit 100) x order by 
x.order_id desc limit 1;

Сначала выберите топ-100 строк, упорядочив их по возрастанию, а затем выберите последнюю строку, упорядочившись в порядке убывания и предел до 1. Однако это очень дорогостоящий оператор, когда он дважды обращается к данным.

0
ответ дан Dwipam Katariya 15 August 2018 в 20:30
поделиться

Например, если вы хотите выбрать каждую 10-ю строку в MSSQL, вы можете использовать:

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY ColumnName1 ASC) AS rownumber, ColumnName1, ColumnName2
  FROM TableName
) AS foo
WHERE rownumber % 10 = 0

Просто возьмите MOD и измените номер 10 на любой номер, который вы хотите.

2
ответ дан E-A 15 August 2018 в 20:30
поделиться

Я не уверен ни в одном из остальных, но я знаю, что SQLite и MySQL не имеют никакого упорядочения строк по умолчанию. В этих двух диалектах, по крайней мере, следующий фрагмент захватывает 15-ю запись из таблицы, сортируя по дате / времени, когда она была добавлена:

SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15

(конечно, вам нужно будет добавить DATETIME и установите дату / время, в которое была добавлена ​​запись ...)

25
ответ дан Ellen Teapot 15 August 2018 в 20:30
поделиться
  • 1
    Это выглядит как лучший способ ограничить запрос значением встроенного смещения. Но разве мы не должны использовать здесь 0,14? 1,15 покинет первый ряд. – Gladiator 23 July 2014 в 14:11
  • 2
    Что означает 15? Я знаю, что 1 говорит, чтобы получить одну запись. Запятая не используется в примере, который я проверил 1keydata.com/sql/sql-limit.html – committedandroider 6 February 2015 в 07:25
  • 3
    Собственно, отсюда php.about.com/od/mysqlcommands/g/Limit_sql.htm , если вы хотите захватить 15-ю запись, вы бы не сделали LIMIT 14, 1 (0-й - это первый элемент , 1 длины – committedandroider 6 February 2015 в 07:27
  • 4
    это sholud будет SELECT * FROM the_table ORDER BY добавлено DESC LIMIT 15,1 – JerryGoyal 27 April 2016 в 06:28
SELECT
    top 1 *
FROM
    table_name
WHERE
    column_name IN (
        SELECT
            top N column_name
        FROM
            TABLE
        ORDER BY
            column_name
    )
ORDER BY
    column_name DESC

Я написал этот запрос для поиска N-й строки. Пример с этим запросом будет

SELECT
    top 1 *
FROM
    Employee
WHERE
    emp_id IN (
        SELECT
            top 7 emp_id
        FROM
            Employee
        ORDER BY
            emp_id
    )
ORDER BY
    emp_id DESC
79
ответ дан Faisal 15 August 2018 в 20:30
поделиться

В Sybase SQL Anywhere:

SELECT TOP 1 START AT n * from table ORDER BY whatever

Не забывайте ORDER BY или это бессмысленно.

1
ответ дан Graeme Perrow 15 August 2018 в 20:30
поделиться

Вот общая версия sproc, которую я недавно написал для Oracle, которая позволяет динамически подкачки / сортировка - HTH

-- p_LowerBound = first row # in the returned set; if second page of 10 rows,
--                this would be 11 (-1 for unbounded/not set)
-- p_UpperBound = last row # in the returned set; if second page of 10 rows,
--                this would be 20 (-1 for unbounded/not set)

OPEN o_Cursor FOR
SELECT * FROM (
SELECT
    Column1,
    Column2
    rownum AS rn
FROM
(
    SELECT
        tbl.Column1,
        tbl.column2
    FROM MyTable tbl
    WHERE
        tbl.Column1 = p_PKParam OR
        tbl.Column1 = -1
    ORDER BY
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 1, Column1, 'X'),'X'),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 1, Column1, 'X'),'X') DESC,
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate) DESC
))
WHERE
    (rn >= p_lowerBound OR p_lowerBound = -1) AND
    (rn <= p_upperBound OR p_upperBound = -1);
2
ответ дан Greg Hurlman 15 August 2018 в 20:30
поделиться

Проверьте его на SQL Server:

Select top 10 * From emp 
EXCEPT
Select top 9 * From emp

Это даст вам 10-ю строку таблицы emp!

11
ответ дан guitarthrower 15 August 2018 в 20:30
поделиться
  • 1
    Вы уже дали ответ на этот вопрос здесь Удалите этот ответ, который, по вашему мнению, не прав. Если вы считаете, что оба ответа правильные, тогда отправьте оба ответа в одном месте – SpringLearner 16 October 2014 в 12:04

В Oracle 12c вы можете использовать опцию OFFSET..FETCH..ROWS с ORDER BY

Например, чтобы получить 3-ю запись сверху:

SELECT * 
FROM   sometable
ORDER BY column_name
OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY;
0
ответ дан Kaushik Nayak 15 August 2018 в 20:30
поделиться

LIMIT n, 1 не работает в MS SQL Server. Я думаю, что это просто единственная основная база данных, которая не поддерживает этот синтаксис. Справедливости ради, он не является частью стандарта SQL, хотя он так широко поддерживается, что он должен быть. Во всем, кроме SQL Server LIMIT, отлично работает. Для SQL-сервера я не смог найти элегантное решение.

2
ответ дан Kibbee 15 August 2018 в 20:30
поделиться
  • 1
    За исключением Oracle, DB2, всего около каждой базы данных уровня предприятия во всем мире. PostgreSQL - это единственная корпоративная база данных, которая поддерживает ключевое слово LIMIT, и это в основном потому, что, будучи открытым исходным кодом, он должен быть доступен доступной для ACID незнакомой толпе MySQL. – David 6 March 2009 в 14:39
  • 2
    @AlexD Этот & quot; ответ & quot; был отправлен назад в старые времена Stackoverflow до того, как были выполнены комментарии. Я бы разместил это как комментарий к другому ответу, но вовремя комментариев не было. – Kibbee 28 August 2012 в 17:33

T-SQL - выбор N'th RecordNumber из таблицы

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from TableName) T where T.Rno = RecordNumber

Where  RecordNumber --> Record Number to Select
       TableName --> To be Replaced with your Table Name

. для выбора 5-й записи из таблицы Employee, ваш запрос должен быть

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from Employee) T where T.Rno = 5
1
ответ дан LPL 15 August 2018 в 20:30
поделиться

Oracle:

select * from (select foo from bar order by foo) where ROWNUM = x
6
ответ дан Mark Harrison 15 August 2018 в 20:30
поделиться

невероятно, что вы можете найти механизм SQL, выполняющий этот ...

WITH sentence AS
(SELECT 
    stuff,
    row = ROW_NUMBER() OVER (ORDER BY Id)
FROM 
    SentenceType
    )
SELECT
    sen.stuff
FROM sentence sen
WHERE sen.row = (ABS(CHECKSUM(NEWID())) % 100) + 1
0
ответ дан Michael Fredrickson 15 August 2018 в 20:30
поделиться

Так я буду делать это в DB2 SQL, я считаю, что RRN (относительный номер записи) хранится в таблице по O / S;

SELECT * FROM (                        
   SELECT RRN(FOO) AS RRN, FOO.*
   FROM FOO                         
   ORDER BY RRN(FOO)) BAR             
 WHERE BAR.RRN = recordnumber
0
ответ дан RDKells 15 August 2018 в 20:30
поделиться

Ничего особенного, никаких специальных функций, если вы используете Caché, как я ...

SELECT TOP 1 * FROM (
  SELECT TOP n * FROM <table>
  ORDER BY ID Desc
)
ORDER BY ID ASC

Учитывая, что у вас есть столбец идентификатора или столбец datestamp, которому вы можете доверять.

0
ответ дан Scott Beeson 15 August 2018 в 20:30
поделиться

Для SQL-сервера следующее возвращает первую строку из таблицы.

declare @rowNumber int = 1;
    select TOP(@rowNumber) * from [dbo].[someTable];
EXCEPT
    select TOP(@rowNumber - 1) * from [dbo].[someTable];

Вы можете прокручивать значения примерно так:

WHILE @constVar > 0
BEGIN
    declare @rowNumber int = @consVar;
       select TOP(@rowNumber) * from [dbo].[someTable];
    EXCEPT
       select TOP(@rowNumber - 1) * from [dbo].[someTable];  

       SET @constVar = @constVar - 1;    
END;
0
ответ дан sony vizio 15 August 2018 в 20:30
поделиться

Я подозреваю, что это дико неэффективно, но довольно простой подход, который работал на небольшом наборе данных, в котором я его пробовал.

select top 1 field
from table
where field in (select top 5 field from table order by field asc)
order by field desc

Это получило бы 5-й элемент, изменив второй верхний номер для получения другого n-го элемента

SQL-сервера (я думаю), но должен работать над более старыми версиями, которые не поддерживают ROW_NUMBER ().

16
ответ дан Tim Saunders 15 August 2018 в 20:30
поделиться
  • 1
    Я буду использовать это, поскольку ROW_NUMBER () не работает в SQL 2000 (да, у нас есть клиент на SQL 2000). В частности, я собираюсь заменить «5» на переменную итератора цикла и использовать чтобы скопировать и изменить каждую строку таблицы по очереди. Возможно, кто-то увидит этот комментарий и найдет это полезным – Inversus 17 May 2013 в 21:02

В отличие от некоторых ответов, стандарт SQL не умалчивает об этом предмете.

Начиная с SQL: 2003, вы могли использовать «функции окна» для пропуска строк и ограничения наборов результатов.

И в SQL: 2008 был добавлен несколько более простой подход, используя
OFFSET skip ROWS FETCH FIRST n ROWS ONLY

Лично я не думаю, что добавление SQL: 2008 было действительно необходимо, поэтому, если Я был ISO, я бы сохранил его из уже довольно большого стандарта.

8
ответ дан Troels Arvin 15 August 2018 в 20:30
поделиться
  • 1
    Приятно, что есть стандарт, тем более упрощает жизнь людей, как и я, и так мило с Microsoft, чтобы делать вещи стандартным образом :) – user230910 15 January 2018 в 03:08

Для SQL Server общий путь по номеру строки таков: SET ROWCOUNT @row - @ row = номер строки, с которой вы хотите работать.

Например:

set rowcount 20 - устанавливает строку до 20-й строки

выберите мясо, сыр из dbo.sandwich - выберите столбцы из таблицы в 20-й строке

set rowcount 0 - устанавливает rowcount обратно во все строки

Это вернет информацию 20-й строки. Обязательно добавьте строку 0 после.

Я знаю noobish, но я SQL noob, и я использовал его так, что я могу сказать?

1
ответ дан user 15 August 2018 в 20:30
поделиться

1 небольшое изменение: n-1 вместо n.

select *
from thetable
limit n-1, 1
11
ответ дан user1357154 15 August 2018 в 20:30
поделиться

Мне кажется, что для того, чтобы быть эффективным, вам нужно: 1) создать случайное число от 0 до единицы меньше, чем количество записей в базе данных, и 2) иметь возможность выбирать строку в этой позиции. К сожалению, разные базы данных имеют разные генераторы случайных чисел и различные способы выбора строки в позиции в наборе результатов - обычно вы указываете, сколько строк нужно пропустить и сколько строк вы хотите, но для разных баз данных это делается по-разному. Вот что работает для меня в SQLite:

select * 
from Table 
limit abs(random()) % (select count(*) from Words), 1;

Это зависит от возможности использования подзапроса в предложении limit (который в SQLite является LIMIT & lt; recs для пропуска & gt;, & lt; recs взять & gt;) Выбор количества записей в таблице должен быть особенно эффективным, являясь частью метаданных базы данных, но это зависит от реализации базы данных. Кроме того, я не знаю, будет ли запрос фактически создавать набор результатов до получения N-й записи, но я надеюсь, что это не понадобится. Обратите внимание, что я не указываю предложение «order by». Возможно, лучше «упорядочить» что-то вроде первичного ключа, который будет иметь индекс - получение N-й записи из индекса может быть более быстрым, если база данных не сможет получить N-й запись из самой базы данных, не создавая набор результатов .

0
ответ дан user1738579 15 August 2018 в 20:30
поделиться
79
ответ дан Faisal 5 September 2018 в 19:50
поделиться
82
ответ дан Faisal 29 October 2018 в 03:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: