sql - T-Sql 选择 * 30% 到 40% 之间

标签 sql sql-server sql-server-2005 tsql stored-procedures

问题

  • 如何编写 T-SQL 存储过程来选择 X% 和 Y% 之间的行百分比?
  • 所以基本上我想选择 30 PERCENT 和 40 PERCENT 之间的行......

我知道您可以执行以下操作,但显然这不允许 met 指定 2 个百分比之间的一组行。

SELECT TOP 50 PERCENT * FROM tblAssets 

非常感谢您的帮助。

最佳答案

更新答案

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 个问题

  1. 性能 - 它被嵌套的 TOP 解决方案击败
  2. 准确性 - NTILE 有一个我没有意识到的意想不到的方面

If the number of rows in a partition is not divisible by integer_expression, this will cause groups of two sizes that differ by one member. Larger groups come before smaller groups in the order specified by the OVER clause. For example if the total number of rows is 53 and the number of groups is five, the first three groups will have 11 rows and the two remaining groups will have 10 rows each.

与嵌套的 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

给予

Table 'spt_values'. Scan count 1, logical reads 8, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'spt_values'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 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

给予

Table 'Worktable'. Scan count 1, logical reads 4726, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'spt_values'. Scan count 1, logical reads 8, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 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

关于sql - T-Sql 选择 * 30% 到 40% 之间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3214113/

相关文章:

sql - 将日期范围分组为 15 天的滚动组

SQL - 使用 sum() 检索获得值的第一行

sql-server - 如何在 SQL Server 中将 bool 字段从可为 null 的列中删除?

sql - 如何在sql server 2005中使用具有多个值的like条件?

sql - 按包含数组的 JSON 列分组

sql - 存储大型 SQL 数据的查询和计数的最有效方法

sql - SQL Server 上的 (nolock) 和表别名的顺序

sql - 仅获取 Y 列中最靠近 X 列的行

sql - T-SQL : How to return 0 rows in from stored procedure, 以及如何使用 XACT_ABORT 和 TRY/CATCH

sql - has_many :through multiple has_one relationships?