正如一位评论者所暗示的,你必须有某种“排序”......我已经介绍了一个表键,你可以将 Over/OrderBY 更改为已经存在的东西......但你必须有某种除了“here they are”之外的排序机制。
我并不是说我的查询是最短的查询...但是,当我有“时髦的业务规则”时,我会选择稍微冗长而不是简洁,所以如果我必须回去维护它,我可以以某种有意义的方式分解“部分”。
这是一个能让你大部分时间到达那里的答案。
基本上,我会根据您的标准去寻找“MagicNewRow”。
但它之所以有效,是因为我能够根据某种排序机制创建一个 ComputedRowId。 (正如我之前解释的)
declare @holder table (TableKey int identity(1,1) ,
Col1 int, Col2 decimal, Col3 bit , Col4 smalldatetime , ComputedRowID int )
insert into @holder (Col1, Col2, Col3, Col4)
select 1 , 10.00 , 0, '2015-01-01'
union all select 1 , 15.00,1, '2015-01-02'
union all select 1 , -15.00, 0, '2015-01-03'
union all select 2 , 5.00, 1, '2015-01-03'
union all select 2 , -5.00, 0, '2015-01-05'
union all select 3 , 1.00, 1, '2015-01-03'
union all select 3 , 2.00, 0, '2015-01-04'
union all select 3 , -1.00, 0, '2015-01-05'
--select * from @holder
Update @holder Set ComputedRowID
= derived1.ROWID
from
@holder hold join
--Select * from
(
select TableKey, Col1, Col2, Col3, Col4 , ROW_NUMBER() over (order by TableKey) as ROWID
from @holder) as derived1
on hold.TableKey = derived1.TableKey
/*
f C=1 then find the next row where B is the negative of B in the row
where C=1 and the value of A is the same for both rows.
If the difference in D between those 2 rows is greater than 1 day,
then return that row where C=1*/
;WITH
cteCIsOne /*Col1, Col2, Col3, Col4, ROWID )*/
AS
(
Select holderAlias.Col1, holderAlias.Col2, holderAlias.Col3, holderAlias.Col4, holderAlias.ComputedRowID
from @holder holderAlias
where Col3 = 1
)
,
cteRowsGreaterThanCurrentRowIdAndNegRuleApplies /*(Col1, Col2, Col3, Col4, ROWID )*/
AS
(
Select holderAlias.Col1, holderAlias.Col2, holderAlias.Col3, holderAlias.Col4,
holderAlias.ComputedRowID,
MagicNextRowComputedRowID = (select top 1 ComputedRowID from cteCIsOne cte1
where holderAlias.ComputedRowID > cte1.ComputedRowID and holderAlias.col2 = (-1 * cte1.col2) )
from @holder holderAlias
)
Select Col1, Col2, Col3, Col4 , ComputedRowID , MagicNextRowComputedRowID, MagicNextRowDate
, MyDateDiff = datediff(d, MagicNextRowDate, Col4)
from
(
SELECT Col1, Col2, Col3, Col4 , ComputedRowID , MagicNextRowComputedRowID
,
MagicNextRowDate = (select top 1 Col4 from @holder hold where hold.ComputedRowID = cteAlias2.MagicNextRowComputedRowID)
from cteRowsGreaterThanCurrentRowIdAndNegRuleApplies cteAlias2
) as derived
where derived.MagicNextRowComputedRowID IS NOT NULL
and
datediff(d, MagicNextRowDate, Col4) > 1