#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 будут динамически заданы на основе цикла, который заполнял таблицу для меня.
В любом случае, я решил свою проблему.