Есть способ для подкачки с использованием только ANSI SQL? - PullRequest
9 голосов
/ 21 января 2009

Я знаю:

  • Жар-птица: FIRST и SKIP;
  • MySQL: LIMIT;
  • SQL Server: ROW_NUMBER();

Кто-нибудь знает способ SQL ANSI для выполнения подкачки результатов?

Ответы [ 8 ]

6 голосов
/ 21 января 2009

См. Предел - со смещением раздел на этой странице: http://troels.arvin.dk/db/rdbms/

Кстати, Firebird также поддерживает предложение ROWS начиная с версии 2.0

2 голосов
/ 11 сентября 2018

В настоящее время существует стандарт, не обязательно стандарт ANSI (люди дали много ответов, я думаю, что это менее подробный)

SELECT * FROM t1 
WHERE ID > :lastId
ORDER BY ID
FETCH FIRST 3 ROWS ONLY

Хотя это поддерживается не всеми базами данных, ниже приведен список всех баз данных, которые поддерживают

  • MariaDB: поддерживается начиная с версии 5.1 (обычно используется лимит / смещение)
  • MySQL: поддерживается начиная с версии 3.19.3 (обычно используется лимит / смещение)
  • PostgreSQL: поддерживается начиная с PostgreSQL 8.4 (обычно используется лимит / смещение)
  • SQLite: поддерживается с версии 2.1.0
  • Db2 LUW: поддерживается с версии 7
  • Oracle: поддерживается начиная с версии 12c (используются подвыборы с помощью функции row_num)
  • Microsoft SQL Server: поддерживается с 2012 года (традиционно используется top-N)

Конечно, вы можете использовать стиль смещения, хотя у вас могут быть проблемы с производительностью

SELECT * FROM t1
ORDER BY ID
OFFSET 0 ROWS
FETCH FIRST 3 ROWS ONLY

Имеет другую поддержку

  • MariaDB: поддерживается с 5.1
  • MySQL: поддерживается с 4.0.6
  • PostgreSQL: поддерживается с PostgreSQL 6.5
  • SQLite: поддерживается с версии 2.1.0
  • Db2 LUW: поддерживается с версии 11.1
  • Oracle: поддерживается с версии 12c
  • Microsoft SQL Server: поддерживается с 2012 года
2 голосов
/ 21 января 2009

Официально нет, нет. *

Как правило, вам понадобится абстрагированная функция на уровне доступа к базе данных, которая будет справляться с вами; намекните, что вы находитесь на MySQL или PostgreSQL, и он может добавить к вашему запросу предложение LIMIT или rownum над подзапросом для Oracle и так далее. Если он не знает, что может сделать что-то из этого, вернитесь к извлечению лота и возвращению только части полного списка.

*: eta: есть сейчас, в ANSI SQL: 2003. Но это не поддерживается глобально, часто работает плохо, и это немного болезненно, потому что вам нужно переместить / скопировать ваш ORDER в новое место в выражении, что усложняет автоматическое перенос:

SELECT * FROM (
    SELECT thiscol, thatcol, ROW_NUMBER() OVER (ORDER BY mtime DESC, id) AS rownumber
)
WHERE rownumber BETWEEN 10 AND 20 -- care, 1-based index
ORDER BY rownumber;

Существует также суффикс "FETCH FIRST n ROWS ONLY" в SQL: 2008 (и DB2, где он возник). Но, подобно префиксу TOP в SQL Server и аналогичному синтаксису в Informix, вы не можете указать начальную точку, поэтому вам все равно придется выбирать и выбрасывать некоторые строки.

1 голос
/ 21 января 2009

Я бы проверил ответы на на этот вопрос - скорее всего, вы начнете.

0 голосов
/ 14 мая 2015

Для подкачки нам нужен столбец RowNo для фильтрации по нему, то есть он должен быть над полем, например id, с двумя переменными, такими как @PageNo и @PageRows. Поэтому я использую этот запрос:

SELECT *
FROM (
    SELECT *, (SELECT COUNT(1)
               FROM aTable ti
               WHERE ti.id < t.id) As RowNo
    FROM aTable t) tr
WHERE
    tr.RowNo >= (@PageNo - 1) * @PageRows + 1 
 AND
    tr.RowNo <= @PageNo * @PageRows 
0 голосов
/ 03 июня 2010
ANSI Sql example:
offset=41, fetchsize=10

SELECT TOP(10) *
FROM table1
WHERE table1.ID NOT IN (SELECT TOP(40) table1.ID FROM table1)
0 голосов
/ 29 августа 2009

Кстати, Troels, PostgreSQL поддерживает ограничение / смещение

0 голосов
/ 21 января 2009

Вставьте результаты в таблицу хранения, упорядочив их так, как вы хотите их отобразить, но с новым столбцом IDENTITY.

Теперь ВЫБЕРИТЕ из этой таблицы только диапазон идентификаторов, которые вас интересуют.

(Обязательно очистите стол, когда закончите)


Или сделайте это на клиенте, поскольку обычно ничего не нужно делать с презентацией на SQL Server (на мой взгляд)

...