Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-Sql选择*介于30%和40%之间 问题: 如何编写一个T-SQL存储过程来选择X%和Y%之间的行百分比 所以基本上我想选择30%到40%之间的行_Sql_Sql Server_Sql Server 2005_Tsql_Stored Procedures - Fatal编程技术网

T-Sql选择*介于30%和40%之间 问题: 如何编写一个T-SQL存储过程来选择X%和Y%之间的行百分比 所以基本上我想选择30%到40%之间的行

T-Sql选择*介于30%和40%之间 问题: 如何编写一个T-SQL存储过程来选择X%和Y%之间的行百分比 所以基本上我想选择30%到40%之间的行,sql,sql-server,sql-server-2005,tsql,stored-procedures,Sql,Sql Server,Sql Server 2005,Tsql,Stored Procedures,我知道您可以执行以下操作,但显然这不允许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

我知道您可以执行以下操作,但显然这不允许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
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
我已经更新了我的答案,因为下面我的原始答案有两个问题

  • 性能-它被嵌套的
    TOP
    解决方案击败
  • 准确性-我没有意识到NTILE有一个意想不到的方面
  • 如果分区中的行数 不可除以 整数_表达式,这将导致 两个尺寸相差一个的组 成员。更大的群体走在前面 按指定顺序排列的较小组 根据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_值”。扫描计数1, 逻辑读取8,物理读取0, 预读读取0,lob逻辑读取 0,lob物理读取0,lob 预读为0

    桌子 “spt_值”。扫描计数1,逻辑 读取5,物理读取0,预读 读取0,lob逻辑读取0,lob 物理读取0,lob预读读取 0

    给予

    表“工作台”。扫描计数1, 逻辑读取4726,物理读取0, 预读读取0,lob逻辑读取 0,lob物理读取0,lob 预读为0

    桌子 “spt_值”。扫描计数1,逻辑 读取8,物理读取0,预读 读取0,lob逻辑读取0,lob 物理读取0,lob预读读取 0

    原始答案

    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
    
    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
    

    这是我自己想出来的

    SELECT TOP 40 *  
        INTO #TOP40
        FROM CCDtblAssets
    
     SELECT * FROM #TOP40
    WHERE ASSETID NOT IN   
    (SELECT TOP 30 ASSETID FROM #TOP40)
    

    虽然我确实喜欢马丁斯的回答。

    +1:很好。我真的需要学习SQL Server中所有新的OVER函数。我认为排名前25%的人排在前40%之后。看起来干净多了,真有趣!前几天我在想,如果没有自己定义水桶的能力,NTILE是无用的…@Goober-是的。我只想对照汤姆建议的答案核对一下执行计划。我会让你知道结果。我不太确定我是否理解语法……我对T-SQl相当陌生。为什么要在“SELECT tblAssets.AssetId”后面加“…”——假设不是syntax@Goober-因为我从不使用“*”,所以它只是一个替换。。。与您的实际列列表!