Выборка записей с N по M
От: Par-zzz  
Дата: 16.10.03 04:36
Оценка:
Всем, доброго времени суток!

Такой вопрос: если я делаю выборку из некоторой таблицы с сортировкой по некоторому признаку, а затем хочу получить из этой выборки записи с диапазонам номеров с N по M. Как я это могу сделать?

вот так быть должно

исходная таблица:

с1 с2
1 a
2 w
3 q
4 t

теперь сортируем по c2

1 a
3 q
4 t
2 w

а теперь надо получить записи для N = 1, а M = 2, т.е.

3 q
4 t

как это можно сделать, какие варианты есть?
/**
* у человека столько проблем, сколько он их себе создает
*/
Re: Выборка записей с N по M
От: Aquary Россия https://wmspanel.com/
Дата: 16.10.03 04:47
Оценка:
Здравствуйте, Par-zzz, Вы писали:

PZ>как это можно сделать, какие варианты есть?


Если на MySQL делается — есть LIMIT "с_какой_записи", "сколько записей"
https://wmspanel.com/nimble — Nimble Streamer media server for live and VOD HLS, RTMP, HTTP streaming
https://wmspanel.com/ — Control and reporting panel for Wowza and Nimble Streamer
http://scm-notes.blogspot.com/ — Блог об управлении конфигурацией
Re: Выборка записей с N по M
От: Adony  
Дата: 16.10.03 04:49
Оценка:
Здравствуйте, Par-zzz, Вы писали:

PZ>Всем, доброго времени суток!


PZ>Такой вопрос: если я делаю выборку из некоторой таблицы с сортировкой по некоторому признаку, а затем хочу получить из этой выборки записи с диапазонам номеров с N по M. Как я это могу сделать?


PZ>как это можно сделать, какие варианты есть?


Посмотрите здесь
Re: Выборка записей с N по M
От: Sergey Ten http://www.fastalgo.com
Дата: 16.10.03 05:03
Оценка:
Здравствуйте, Par-zzz, Вы писали:

PZ>Всем, доброго времени суток!


PZ>Такой вопрос: если я делаю выборку из некоторой таблицы с сортировкой по некоторому признаку, а затем хочу получить из этой выборки записи с диапазонам номеров с N по M. Как я это могу сделать?


PZ>вот так быть должно


PZ>исходная таблица:


PZ>с1 с2

PZ>1 a
PZ>2 w
PZ>3 q
PZ>4 t

PZ>теперь сортируем по c2


PZ>1 a

PZ>3 q
PZ>4 t
PZ>2 w

PZ>а теперь надо получить записи для N = 1, а M = 2, т.е.


PZ>3 q

PZ>4 t

PZ>как это можно сделать, какие варианты есть?


В Oracle можно использовать трюк с псевдоколонкой rownum:

select c1, c2 from (
  select c1, c2, rownum rn from 
  (select c1, c2 from t order by c2)  
   where rownum <= :M + 1) 
where rn >= :N + 1

C1    C2

3    q
4    t

Так как rownum базируетеся с единицы, а в вашем примере N и M — с нуля, то используются :N+1 и :M+1.
Re: Выборка записей с N по M
От: anonymous Россия http://denis.ibaev.name/
Дата: 16.10.03 05:03
Оценка:
Здравствуйте, Par-zzz, Вы писали:

PZ>Всем, доброго времени суток!


<skip/>

PZ>как это можно сделать, какие варианты есть?



SELECT *
FROM <таблица>
ORDER BY c2
LIMIT <N>,<M-N+1>
Re: Выборка записей с N по M
От: Archistratig Россия  
Дата: 16.10.03 05:38
Оценка:
Здравствуйте, Par-zzz, Вы писали:

PZ>Всем, доброго времени суток!


PZ>Такой вопрос: если я делаю выборку из некоторой таблицы с сортировкой по некоторому признаку, а затем хочу получить из этой выборки записи с диапазонам номеров с N по M. Как я это могу сделать?


Лучшее решение я видел здесь
Автор: Alex Warm
Дата: 09.09.03
:

От: Alex Warm
Дата: 09.09.03 11:34
Оценка: 4 (1)

Здравствуйте, Archistratig!
Давненько я тут не появлялся, но было время когда Вы писали:

A>Сортирован — это слишком строгое требование. Вся эта схема работала бы, если бы в SQL существовала конструкция не TOP <n>, а нечто вроде FROM_ROW <m> TO_ROW <n>. Эмулировать ее пратически нереально кроме специальных случаев (вроде вставить результирующую выборку в темповую таблицу с identity и мделать еще один SELECT из нее и прочая неэффективная экзотика).


Когда-то я тоже сталкивался с такой проблеммой. Добрые люди подсказали решение.
К примеру P — номер страницы
N — количество записей на странице
тогда получается следующая картина для 5 страницы из 20 записей

select * from
(select top 20 * from 
(select top 100 * from tbl order by tbl_id) as tmp1
order by tmp1.tbl_id desc) as tmp2
order by tmp2.tbl_id


На выходе получится именно то, что вы и хотели <from 80 to 100>
Re[2]: Выборка записей с N по M
От: Merle Австрия http://rsdn.ru
Дата: 16.10.03 07:40
Оценка: 11 (1)
Здравствуйте, Archistratig, Вы писали:


A>Лучшее решение я видел здесь
Автор: Alex Warm
Дата: 09.09.03
:


Оно не всегда лучшее...
Дело в том, что значение в top нельзя указать через переменную, а значит каждый раз запрос будет компилироваться заново.
Избежать этого можно переписав этот запрос примерно в таком же виде используя переменную @table и параметр @@ROWCOUNT, куда можно передавать размер в виде переменной.
Мы уже победили, просто это еще не так заметно...
Re[2]: Выборка записей с N по M
От: Андрей Майоров Россия http://blogs.byte-force.com/xor
Дата: 16.10.03 08:23
Оценка:
Здравствуйте, Adony, Вы писали:

A>Посмотрите здесь


FAQ ясен, но не полон. Там не рассмотрен, например, еще способ выполнения этого действия при помощи курсора. Операция простая: открываем статический курсор с возможностью абсолютного позиционирования, переходим на запись N и достаем M записей. Казалось бы, это медленно, но элементарный тест показывает, что курсором доставать быстрее, чем используя временную таблицу. Впрочем, тестом я занимался недолго, мог сделать какие-то ошибки. Так что, можно подвергать мои слова сомнению и пробовать. Дело недолгое.

Да, речь идет об MSSQL 2k

WBR,
XOR
... << RSDN@Home 1.1 beta 2 >>
WBR,
XOR // BYTE-force
Re[3]: Выборка записей с N по M
От: Merle Австрия http://rsdn.ru
Дата: 16.10.03 10:00
Оценка:
Здравствуйте, Андрей Майоров, Вы писали:

АМ> Казалось бы, это медленно, но элементарный тест показывает, что курсором доставать быстрее, чем используя временную таблицу. Впрочем, тестом я занимался недолго, мог сделать какие-то ошибки. Так что, можно подвергать мои слова сомнению и пробовать. Дело недолгое.

АМ> Да, речь идет об MSSQL 2k

Ну, по моим данным через переменную table все-таки быстрее...
Мы уже победили, просто это еще не так заметно...
Re[4]: Выборка записей с N по M
От: Андрей Майоров Россия http://blogs.byte-force.com/xor
Дата: 17.10.03 08:10
Оценка:
Здравствуйте, Merle, Вы писали:

M>Ну, по моим данным через переменную table все-таки быстрее...


Айда проверять.

Имеется таблица test1 с 10000 записей. Делаем две процедуры, по-разному реализующие постраничный вывод.

--    PageCursor

CREATE PROCEDURE dbo.PageCursor 
as begin

    set nocount on

    declare @cSteps cursor
    set    @cSteps = cursor static for
        select    id
        from    test1
        order by f1, f2
        
    open @cSteps
    declare     @iObject int

    declare @i int
    set @i = 0
    fetch    absolute 210
        from    @cSteps
        into    @iObject    

    while @i < 10  begin
        select cast (210+@i as varchar(10)) as n, cast(  @iObject as varchar(10)) as id

        fetch    next from @cSteps
        into    @iObject
        if @@fetch_status <> 0
            break
        set    @i = @i+1
    end

    close @cSteps
    deallocate @cSteps

end
GO


-- PageNoCursor

CREATE PROCEDURE dbo.PageNoCursor 
AS begin

set nocount on

declare @tTemp table( n int identity(1, 1), id int )

insert into @tTemp( id )
select    id
from    test1
order by f1, f2

select    *
from    @tTemp
where    n >= 210 and n < 220

end
GO


Имеем вот такой (донельзя элементарный) механизм замера производительности:

set nocount on
declare @d datetime
set    @d = getdate()
exec pagenocursor
select getdate() - @d 
set    @d = getdate()
exec pagecursor
select getdate() - @d


На выходе имеем: курсор всегда примерно в полтора раза быстрее. При этом важно, какой метод идет сначала. Если сначала выполняем безкурсорный вариант, то разница скачет от 3-х раз до 1 (курсор быстрее или так же). Если сначала курсорный, то разница как раз примерно полтора раза. Что интересно, время выполнения курсорного варианта скачет в существенно меньших пределах.

WBR,
XOR
... << RSDN@Home 1.1 beta 2 >>
WBR,
XOR // BYTE-force
Re[5]: Выборка записей с N по M
От: Merle Австрия http://rsdn.ru
Дата: 17.10.03 08:24
Оценка:
Здравствуйте, Андрей Майоров, Вы писали:

АМ> Айда проверять.

Честно? лень..

АМ> На выходе имеем: курсор всегда примерно в полтора раза быстрее. При этом важно, какой метод идет сначала. Если сначала выполняем безкурсорный вариант, то разница скачет от 3-х раз до 1 (курсор быстрее или так же). Если сначала курсорный, то разница как раз примерно полтора раза. Что интересно, время выполнения курсорного варианта скачет в существенно меньших пределах.


1. Мерять лучше через
SET STATISTICS TIME

2. Есть ли индекс хотя бы по ID в основной таблице?
3. Я в свое время мерял с более сложной таблицей, больше данных и помоему таблица была не одна. Фокус в том, что в случае курсора надо сразу тянуть все данные, а потом заниматься изнурительным скроллингом по ним, а во временную таблицу можно слить нужные ID'шники, а потом сджойнить ее с основной/основными.
4. В процессе меряния лучше менять номера страниц и, редко, размер страниц. Тоесть надо написать полноценные процедуры для пэйджинга и погонять их.
Мы уже победили, просто это еще не так заметно...
Re[6]: Выборка записей с N по M
От: Андрей Майоров Россия http://blogs.byte-force.com/xor
Дата: 17.10.03 09:42
Оценка:
Здравствуйте, Merle, Вы писали:

M>Здравствуйте, Андрей Майоров, Вы писали:


АМ>> Айда проверять.

M>Честно? лень..

Да и мне тоже лень, в общем-то.

M>1. Мерять лучше через

M>
M>SET STATISTICS TIME
M>


Получается не суммарное время выполнения хранпроцы, а по каждому стейтменту. Несколько неудобно, хотя, может быть, и более аккуратно.

M>2. Есть ли индекс хотя бы по ID в основной таблице?


Конечно. Это праймари key, на нем — кластеризованный индекс

M>3. Я в свое время мерял с более сложной таблицей, больше данных и помоему таблица была не одна. Фокус в том, что в случае курсора надо сразу тянуть все данные, а потом заниматься изнурительным скроллингом по ним, а во временную таблицу можно слить нужные ID'шники, а потом сджойнить ее с основной/основными.


То, что с временной таблицей код проще — это однозначно. С другой стороны, тут код однотипный, можно в шаблон загнать. А насчет того, что таблицы более сложные, так это не важно. Мы все равно в курсоре только ИДы достаем. Если фетчем весь объект получать — запаришься.

M>4. В процессе меряния лучше менять номера страниц и, редко, размер страниц. Тоесть надо написать полноценные процедуры для пэйджинга и погонять их.


Согласен, но делать влом.

WBR,
XOR
... << RSDN@Home 1.1 beta 2 >>
WBR,
XOR // BYTE-force
Re[7]: Выборка записей с N по M
От: Merle Австрия http://rsdn.ru
Дата: 17.10.03 10:09
Оценка:
Здравствуйте, Андрей Майоров, Вы писали:

АМ> А насчет того, что таблицы более сложные, так это не важно. Мы все равно в курсоре только ИДы достаем. Если фетчем весь объект получать — запаришься.

Дык, а нафиг сдались одни ID'шники клиенту? Ему все поля нужны... Тоесть хочешь-не хочешь, а курсором их тащить все придется. Вот тут похоже и случатся основные тормоза.
Мы уже победили, просто это еще не так заметно...
Re[8]: Выборка записей с N по M
От: -arra- Россия  
Дата: 17.10.03 13:50
Оценка:
M>Дык, а нафиг сдались одни ID'шники клиенту? Ему все поля нужны... Тоесть хочешь-не хочешь, а курсором их тащить все придется. Вот тут похоже и случатся основные тормоза.

Предидущий оратор имел ввиду, что ид-шники записей нужной страницы складываются во временную таблицу/переменную далее на выходе ее джойним с остальными данными.

На самом деле получается достаточно оптимально и практически не зависит от номера страницы
Re[8]: Выборка записей с N по M
От: Андрей Майоров Россия http://blogs.byte-force.com/xor
Дата: 17.10.03 14:47
Оценка:
Здравствуйте, Merle, Вы писали:

АМ>> А насчет того, что таблицы более сложные, так это не важно. Мы все равно в курсоре только ИДы достаем. Если фетчем весь объект получать — запаришься.

M>Дык, а нафиг сдались одни ID'шники клиенту? Ему все поля нужны... Тоесть хочешь-не хочешь, а курсором их тащить все придется. Вот тут похоже и случатся основные тормоза.

Дело в том, что мне всегда как раз нужны были именно ИДы. Каждая такая выборка в моем случае может возвратить объекты разных типов, так что приходится сначала находить список ИДов объектов, соответствующих условиям, потом прорезать в нем "окно", а потом уже доставать данные объекта специфично каждой записи.

Так что, как водится, есть ситуации и есть ситуации. Будем знать, что в моем сценарии быстрее использовать курсор, а в некоем случае простой выборки со сложными таблицами — временную таблицу.

WBR,
XOR
... << RSDN@Home 1.1 beta 2 >>
WBR,
XOR // BYTE-force
Re: Выборка записей с N по M
От: Аноним  
Дата: 29.07.07 17:30
Оценка:
Может ли хотя бы один из предложенных способов использовать индекс?
Например, MySQL в случае запроса без условий WHERE, соединений и агрегатных функций, с сортировкой по индексированному набору столбцов позволяет сделать быструю постраничную выборку.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.