Сведения о вопросе

Ислам

03:04, 9th August, 2020

Теги

mysql   sql   database   oracle   postgresql    

Как выбрать N-ю строку в таблице базы данных SQL?

Просмотров: 2918   Ответов: 25

Мне интересно изучить некоторые (в идеале) агностические способы выбора n-й строки из таблицы базы данных. Было бы также интересно посмотреть, как это может быть достигнуто с помощью собственных функциональных возможностей следующих баз данных:

  • SQL сервер
  • MySQL
  • PostgreSQL
  • SQLite
  • Oracle

В настоящее время я делаю что-то вроде следующего в SQL Server 2005, но мне было бы интересно увидеть другие более агностические подходы:

WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000

Кредит за вышеизложенное SQL: веб- блог Фироза Ансари

Update: смотрите ответ Troels Arvin относительно стандарта SQL. Троэльс, у тебя есть какие-нибудь ссылки, которые мы можем привести?



  Сведения об ответе

$DOLLAR

20:52, 3rd August, 2020

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

Действительно хороший сайт, который говорит об этом и других вещах, - это 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

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

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

Update: SQLite добавлена поддержка оконных функций в версии 3.25.0 на 2018-09-15, поэтому обе формы также работают в SQLite.


  Сведения об ответе

SKY

10:19, 20th August, 2020

Синтаксис LIMIT / OFFSET в PostgreSQL является:

SELECT
    *
FROM
    mytable
ORDER BY
    somefield
LIMIT 1 OFFSET 20;

В этом примере выбирается 21-я строка. OFFSET 20 говорит Postgres пропустить первые 20 записей. Если вы не укажете пункт ORDER BY , нет никакой гарантии, что запись будет возвращена, что редко бывает полезно.

По-видимому, стандарт SQL молчит о предельном вопросе за пределами сумасшедших оконных функций, поэтому все реализуют его по-разному.


  Сведения об ответе

9090

13:06, 7th August, 2020

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

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

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


  Сведения об ответе

$DOLLAR

15:19, 29th August, 2020

SQL 2005 и выше имеет эту встроенную функцию. Используйте функцию ROW_NUMBER(). Он отлично подходит для веб-страниц с << Prev и Next > > style browsing:

Синтаксис:

SELECT
    *
FROM
    (
        SELECT
            ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum,
            *
        FROM
            Table_1
    ) sub
WHERE
    RowNum = 23


  Сведения об ответе

davran

19:17, 8th August, 2020

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

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().


  Сведения об ответе

VCe znayu

07:41, 14th August, 2020

Проверьте это на сервере SQL:

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

Это даст вам 10-й ROW из таблицы emp!


  Сведения об ответе

crush

11:53, 10th August, 2020

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

select *
from thetable
limit n-1, 1


  Сведения об ответе

baggs

03:51, 23rd August, 2020

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

Начиная с SQL:2003, вы можете использовать "window functions" для пропуска строк и ограничения результирующих наборов.

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

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


  Сведения об ответе

Chhiki

02:11, 12th August, 2020

Когда мы работали в 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

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


  Сведения об ответе

SILA

13:53, 5th August, 2020

Oracle:

select * from (select foo from bar order by foo) where ROWNUM = x


  Сведения об ответе

fo_I_K

08:23, 7th August, 2020

SQL сервер


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

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


  Сведения об ответе

LIZA

06:31, 21st August, 2020

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

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

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

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

Далее, Если вам нужна сумма, ID или какой-то числовой порядок сортировки, то u может пойти для функции CAST в MySQL.

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

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


  Сведения об ответе

lourence

05:27, 16th August, 2020

ДОБАВЛЯТЬ:

LIMIT n,1

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


  Сведения об ответе

prince

02:18, 1st August, 2020

Например, если вы хотите выбрать каждую 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 здесь на любое число, которое вы хотите.


  Сведения об ответе

lesha

04:15, 8th August, 2020

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


  Сведения об ответе

crush

22:27, 26th August, 2020

Вот общая версия 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);


  Сведения об ответе

VERSUION

02:31, 8th August, 2020

Но на самом деле, разве все это не просто салонные трюки для хорошего дизайна базы данных в первую очередь? Несколько раз я нуждался в такой функциональности, как эта, это было для простого одного запроса, чтобы сделать быстрый отчет. Для любой реальной работы использование подобных трюков чревато неприятностями. Если требуется выбрать конкретную строку, то просто создайте столбец с последовательным значением и покончите с ним.


  Сведения об ответе

SKY

11:43, 4th August, 2020

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

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

SELECT * 
FROM   sometable
ORDER BY column_name
OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY;


  Сведения об ответе

VCe znayu

17:21, 26th August, 2020

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-ю запись из таблицы сотрудника, ваш запрос должен быть

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


  Сведения об ответе

lesha

08:41, 17th August, 2020

В Sybase SQL Любом Месте:

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

Не забывайте о приказе, иначе это бессмысленно.


  Сведения об ответе

lourence

23:45, 16th August, 2020

SELECT * FROM emp a
WHERE  n = (SELECT COUNT( _rowid)
              FROM emp b
             WHERE a. _rowid >= b. _rowid);


  Сведения об ответе

SSESION

23:33, 20th August, 2020

Для сервера SQL общий способ перехода по номеру строки таков:

SET ROWCOUNT @row --@row = the row number you wish to work on.

например:

set rowcount 20   --sets row to 20th row

select meat, cheese from dbo.sandwich --select columns from table at 20th row

set rowcount 0   --sets rowcount back to all rows

Это вернет информацию о 20-й строке. После этого обязательно введите значение rowcount 0.


  Сведения об ответе

ASER

08:35, 14th August, 2020

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


  Сведения об ответе

PROGA

15:11, 29th August, 2020

невероятно, что вы можете найти движок 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


  Сведения об ответе

crush

13:34, 6th August, 2020

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

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться