как разделить таблицу без каких-либо прогрессивных полей?

#sql-server #tsql #partitioning #row-number

Вопрос:

Мне нужно разбить таблицу на разделы, чтобы получить записи в диапазоне значений.

У меня в таблице нет прогрессивного поля.

 select [_Load_Timestamp], [COL_A], [COL_B], [COL_C], [COL_D], [COL_E], [COL_F]
from dbo.table
where ROW_NUMBER() OVER (order by [_Load_Timestamp], [COL_A], [COL_B], [COL_C]) between 500 and 1000;
 

При написании этого кода он возвращает мне следующую ошибку:

 Windowed functions can only appear in the SELECT or ORDER BY clauses.
 

Проблема заключается в ROW_NUMBER() утверждении.

Я могу написать запрос таким образом, но проблема в том, что я должен максимально ограничить доступ к таблице, так как это действительно медленно.

 select *
from ( 
        select ROW_NUMBER() OVER (order by [_Load_Timestamp], [COL_A], [COL_B], [COL_C])) [id]
                ,[_Load_Timestamp], [COL_A], [COL_B], [COL_C], [COL_D], [COL_E], [COL_F]
        from dbo.table
     ) t
where t.id between 500 and 1000;
 

Может ли кто-нибудь дать мне альтернативу для достижения той же цели?

Комментарии:

1. Ваша цель-просматривать большие наборы результатов (500 строк не очень велики, если не задействован графический интерфейс)? Это так, некоторые поисковые запросы в разделе «большие наборы данных подкачки sql server» найдут обсуждения.

Ответ №1:

Попробуйте это:

 ;with MyTable as  
    ( 
        select 
                ROW_NUMBER() OVER (order by [_Load_Timestamp], [COL_A], [COL_B], [COL_C])) [id]
                ,[_Load_Timestamp], [COL_A], [COL_B], [COL_C], [COL_D], [COL_E], [COL_F]
        from dbo.table
     )
select  *
from MyTable
where id between 500 and 1000
;
 

Комментарии:

1. Это решение я уже исключил и искал альтернативу.

2. Нет, это не так. Эта версия с CTE похожа на ту, которая, по вашему мнению, решила вашу проблему с temp. Разница и реальная причина, по которой проблема была решена, могут заключаться в индексе, который вы создали там.

Ответ №2:

Я нашел решение.

 select  ROW_NUMBER() OVER (order by [_Load_Timestamp], [COL_A], [COL_B], [COL_C])) [id], [_Load_Timestamp], [COL_A], [COL_B], [COL_C]
into #tmp_key
from dbo.table

create index IX_01 on #tmp_key on ([id])

select _b.*
from #tmp_key _a
join dbo.table _b on _a.id between 500 and 1000
and _a.[_Load_Timestamp] = _b.[_Load_Timestamp] 
and _a.[COL_A] = _b.[COL_A]
and _a...
 

Числа 500 и 1000 будут динамически заданы на основе цикла, который заполнял таблицу для меня.

В любом случае, я решил свою проблему.