Обновленный ответ
declare @NumRecords int
SELECT @NumRecords = COUNT(*) FROM tblAssets;
With Vals As
(
SELECT tblAssets.AssetId ...
, ROW_NUMBER() OVER ( order by tblAssets.AssetId) as RN
FROM tblAssets
)
SELECT tblAssets.AssetId ...
FROM vals
Where RN between 0.3*@NumRecords and 0.4*@NumRecords
Я обновил свой ответ, так как было 2 проблемы с моим исходным ответом ниже
- Производительность - было побито вложенным
TOP
решением
- Точность - есть неожиданный аспект NTILE, о котором я не знал
Если количество строк в разделе
не делится на
integer_expression, это приведет к
группы двух размеров, которые отличаются на один
член. Большие группы приходят раньше
меньшие группы в указанном порядке
по предложению OVER. Например, если
общее количество строк составляет 53 и
количество групп пять, первое
три группы будут иметь 11 строк и
две оставшиеся группы будут иметь 10 строк
каждый.
Я получил следующие значения по сравнению с вложенным решением TOP
.
SET STATISTICS IO ON
SET STATISTICS TIME ON;
DECLARE @NumRecords int
SELECT @NumRecords = COUNT(*) FROM [master].[dbo].[spt_values];
WITH Vals As
(
SELECT [number]
, ROW_NUMBER() OVER ( order by [number]) as RN
FROM [master].[dbo].[spt_values]
)
SELECT [number] FROM vals Where RN
BETWEEN 0.30*@NumRecords AND 0.40*@NumRecords
Придает
Таблица 'spt_values'. Количество сканирований 1,
логическое чтение 8, физическое чтение 0,
опережающее чтение - 0, логическое чтение -
0, lob физическое чтение 0, lob
упреждающее чтение читает 0.
Таблица
'spt_values'. Сканирование 1, логическое
читает 5, физический читает 0, чтение вперед
читает 0, lob логическое чтение 0, lob
физическое чтение 0, чтение опережающего чтения
0.
SELECT TOP 25 PERCENT [number] FROM
(
SELECT TOP 40 PERCENT [number]
FROM [master].[dbo].[spt_values]
ORDER BY [number] ASC
) TOP40
ORDER BY [number] DESC
Придает
Таблица «Рабочий стол». Количество сканирований 1,
логическое чтение 4726, физическое чтение 0,
опережающее чтение - 0, логическое чтение -
0, lob физическое чтение 0, lob
упреждающее чтение читает 0.
Таблица
'spt_values'. Сканирование 1, логическое
читает 8, физический читает 0, чтение вперед
читает 0, lob логическое чтение 0, lob
физическое чтение 0, чтение опережающего чтения
0.
Оригинальный ответ
With Vals As
(
SELECT tblAssets.AssetId ...
, NTILE (100) OVER ( order by tblAssets.AssetId) as Pct
FROM tblAssets
)
SELECT * FROM vals Where Pct between 30 and 40