2016-07-28 68 views
0

我有一个包含'contracts'的表,使用contractId作为主键。 在另一张表中,我有与这些合同有关的价格(FK contractId)。 我之前必须计算按合同分组的价格之间的价格差异(回报),并且总是在特定的日期期间。所以我只是在利息期间提取每日价格,并将其与前一天的价格进行比较。这并不难。只从第n行检索sql数据

现在我需要再次从相同的数据计算回报,但总是跳过与数量(n)合约相关的价格。 因此对于n = 1我只跳过一个合约。对于n = 2,我需要跳过2个合约... 对于每个合约,我需要再次计算两个价格按日期的回报,但是一旦我完成了让我们说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,我d需要找到与ContractIds相关的价格:

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

我试图使用铅和偏移但我无法找到正确跳过合同并按照需要将相关合同链接起来的方法。 我错过了什么? 在此先感谢!

+0

你可以指定一个行号,只能从表采取ROWNUMBER%n行('WHERE ROWNUMBER%(N + 1)= 1 ''),或者只是'WHERE(contractid - 100000)%(n + 1)= 1' – ZLK

回答

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