Поступил вопрос о том, как можно делать запрос, чтобы выходило определенное количество строк, начиная с заданной. Ясно, что такой вопрос волнует в основном web-программистов, поскольку в обычных клиент-серверных приложениях принято выводить все строки сразу (если их относительно не много), а уже там, в «клиенте» представлять их так, как это надо по сценарию.
Прежде всего, несколько отвлеченных слов о MySQL и вообще о развитии ПО. Это развитие подчиняется вполне определенным закономерностям. Какова особенность MySQL?
1. Он де факто являлся и является основным (но не единственным) инструментом для построения web-приложений (особенно не коммерческих).
2. Это СУБД долгое время не имело средств программирования на стороне сервера.
Оба фактора привели к тому, что в MySQL появились некоторые возможности, которых еще не было в таких тяжеловесных СУБД как Oracle, MS SQL Server и др. Разработчики СУБД старались вместить в командах больше возможностей, чем это было в обычных реализациях SQL. Чтобы компенсировать отсутствие других возможностей.
В частности к этому можно отнести и возможность обновлять одной командой update сразу несколько таблиц и ключевое слово limit в команде select.
С помощью этого слова имеется возможность вывести определенное количество строк в запросе, начиная с заданной. В других СУБД этому уделяли меньше внимания, поскольку на стороне сервера можно написать процедуру, которая будут выполнять это же действие.
Далее речь пойдет о Transact SQL, поскольку именно о нем был задан вопрос. В начале, я приведу пример именно процедуры, которая эту проблему решает. Для этого имеется такой объект как курсор. Вот схема решения
- Код: Выделить всё
create procedure имя
(
--какие-то параметры
…
@n1 int, --номер строки, откуда начинать вывод
@n2 int –количество выводимых строк
)
As
Begin
…
Declare @t table (…) – вы этой таблице и будем выводить результат
…
--объявить курсор
declare cur cursor
local forward_only static –эти параметры можно и опустить
for select … --здесь нужный запрос
--открываем курсор
open cur
fetch next from cur
while @@fetch_status = 0
begin
…
If (условие, например проверяется номер строки и количество строк)
begin
fetch next from cur into … --список переменных
insert into @t1 (список полей) values(список переменных)
end
end
close cur
dealocate cur
--выводим нужные строки
select * from @t
end
Конечно, длинно, но вполне универсально. По сути, вы сами конструируете, что и как надо выводить.
Рассмотрим более короткий путь. Этот путь основывается на одной из функций ранжирования Row_Number(). Эти функции не являются изобретением MS SQl Server, они прописаны в стандарте.
Вот простой пример. Надеюсь из него все ясно.
- Код: Выделить всё
select t1.fio,t1.adres from
(select Row_Number() over (order by fio desc) as n, fio,adres from a) as t1
where t1.n between 2 and 40
Здесь рассматривается запрос к одной таблице, но с тем же успехом можно использовать подобные конструкции и для произвольного количества таблиц. Также обращаю ваше внимание, что в выражении where можно использовать параметры и переменные. Так что все в ваших руках.