仅从每个第n行检索sql数据

时间:2016-07-28 22:43:43

标签: sql-server sql-server-2012

我有一个包含' contract'的表,使用contractId作为主键。 在另一张表中,我有与这些合约相关的价格(FK contractId)。 我之前必须计算按合同分组的价格之间的价格差异(回报),并且总是在特定日期期间。因此,我只是在感兴趣的时间段内获取每天的价格,并将其与前一天的价格进行比较,对于每个合约。这并不难。

现在我需要从相同的数据再次计算回报,但总是跳过与数字(n)合约相关的价格。 所以对于n = 1我只是跳过一个合同。对于n = 2,我需要跳过2个合同...... 对于每个有问题的合同,我需要再次按日期计算两个价格的回报,但是一旦我完成了let' s表示contractId = 1,我需要跳过合约,其中contractId = 2并重新开始计算从我停止计算id = 3的合约的回报的日期开始的回报。 合同清单如下所示:

ContractId  ContractCode
100001  NAM0899
100002  NAM0999
100003  NAM1099
100004  NAM1199
100005  NAM1299
100006  NAM0100
100007  NAM0200
100008  NAM0300
100009  NAM0400
100010  NAM0500

因此对于N = 1,我需要找到与ContractIds相关的价格:

100001, 100003, 100005, 100007
N = 2: 100001, 100004, 100007, 100010...
N = 3: 100001, 100005, 100009, 100013...

我曾尝试使用Lead和Offset,但我无法找到正确跳过合同的方法,并按照我需要的方式将相关合同链接在一起。 我错过了什么? 提前谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用row_number()和模运算:

select loc.*
from (select loc.*,
              row_number() over (order by Contractid) as seqnum
      from listOfContracts loc
     ) loc
where (seqnum - 1 % @n) = 0;

答案 1 :(得分:1)

对WHERE进行了一些调整(我应该阅读评论),但我认为这会产生您想要的结果

Declare @Table table (ContractId int,ContractCode varchar(25))
Insert Into @Table values 
(100001,'NAM0899'),
(100002,'NAM0999'),
(100003,'NAM1099'),
(100004,'NAM1199'),
(100005,'NAM1299'),
(100006,'NAM0100'),
(100007,'NAM0200'),
(100008,'NAM0300'),
(100009,'NAM0400'),
(100010,'NAM0500')

Declare @Rows   int = 2
Declare @RetVal varchar(max) = ''
;with cteBase as (
    Select *,RowNr=Row_Number() over (Order By ContractId) from @Table
)
Select @RetVal = Replace(ltrim(rtrim(concat(@RetVal,' ',ContractId))),' ',',')
 From cteBase
 Where RowNr=1 or (RowNr-1) % (@Rows+1) = 0
 Order by RowNr

Select RetVal=concat('N = ',@Rows,': ',@RetVal)

返回

N = 2: 100001,100004,100007,100010
  

要返回规范化列表,只需使用

替换最终选择
Select ContractId