更新答案
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,
read-ahead 读取 0,lob 逻辑读取
0, lob 物理读取 0, lob
预读为 0。
表
'spt_values'。扫描计数 1,逻辑
读取 5,物理读取 0,预读
读取 0,lob 逻辑读取 0,lob
物理读取 0,lob 预读
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,
read-ahead 读取 0,lob 逻辑读取
0, lob 物理读取 0, lob
预读为 0。
表
'spt_values'。扫描计数 1,逻辑
读取 8,物理读取 0,预读
读取 0,lob 逻辑读取 0,lob
物理读取 0,lob 预读
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