我有下表
EmpId Date StartOn EndOn
0001 2-Feb-17 590 599
0002 2-Feb-17 600 609
0003 2-Feb-17 610 619
0004 2-Feb-17 626 635
0002 2-Feb-17 630 639
0004 2-Feb-17 640 649
0005 3-Feb-17 630 639
我希望输出像这样
EmpId Date StartOn EndOn Overlapping Num
0001 2-Feb-17 590 599 0 1
0002 2-Feb-17 600 609 0 1
0003 2-Feb-17 610 619 0 1
0004 2-Feb-17 626 635 1 1
0002 2-Feb-17 630 639 1 2
0004 2-Feb-17 640 649 0 1
0005 3-Feb-17 630 639 0 1
这里有一个数据样本
create table Data(
EmpId nvarchar(4),
Date date,
StartOn int,
EndOn int
);
insert into Data(EmpId,Date,StartOn,EndOn)
values('0001','02 Feb 2017',590,599),
('0002','02 Feb 2017',600,609),
('0003','02 Feb 2017',610,619),
('0004','02 Feb 2017',626,635),
('0002','02 Feb 2017',630,639),
('0004','02 Feb 2017',640,649),
('0005','03 Feb 2017',630,639)
要求:我想知道之间发生了多少重叠 在给定日期
排序StartOn
和EndOn
并按以下方式对这些重叠进行排序StartOn
,例如EmpId
(0004与范围626之间的EmpId
0002重叠 和639(重叠发生在范围630和635之间),因此Overlapping
列 将保留重叠数,Num
将保持数量 按StartOn
这是我试过的
;with overlapping as(
select a.EmpId,a.Date,a.StartOn,a.EndOn,count(b.EmpId) as Num
from #Data a
left join #Data b on a.Date = b.Date
and a.StartOn<=b.EndOn and a.EndOn>=b.StartOn and b.EmpId<>a.EmpId
group by a.EmpId,a.Date,a.StartOn,a.EndOn
)
select *,rank() over(partition by Date,Num order by StartOn) as Row
from overlapping
order by Date,StartOn,EmpId
我尝试了row_number
和rank
但未能获得任何所需的结果
答案 0 :(得分:1)
我倾向于使用exists
而不是自我加入。然后,在存在的基础上,累积和来定义&#34;组&#34;然后row_number()
:
with d as (
select d.*,
(case when exists (select 1
from #data d2
where d2.StartOn <= d.EndOn and
d2.EndOn >= d.StartOn and
d2.EmpId <> d.EmpId
)
then 1 else 0
end) as IsOverlap
from #data d
)
select d.*, row_number() over (partition by grp order by StartOn) as num
from (select d.*, sum(IsOverlap) over (order by StartOn) as grp
from d
) d;
但是,我并非100%确定这符合您的需求。当有更多重叠时,结果应该是什么?如果EmpId
与他/她自己重叠会怎样?
答案 1 :(得分:0)
这是一种方法:
Server Version: 76
TWS Time at connection:20170319 05:45:12 EST
<managedAccounts accountsList=DU647841>
<nextValidId orderId=1>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm.us>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:cafarm>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:hfarm>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:cashfarm>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfuture>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:jfarm>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm>
<error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usopt>
<error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ushmds.us>
<error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ilhmds>
<error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:euhmds>
<error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:cashhmds>
<error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:fundfarm>
<error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ushmds>
Contract Values:CAD,CASH,IDEALPRO,IDEALPRO,jpy:
* * * * REQUESTING MARKET DATA * * * *
('global variables:', None, None, None)
last close: 85.07
* * * * CANCELING MARKET DATA * * * *
使用您提供的样本数据,结果为:
;WITH CTE AS
(
SELECT EmpId,
[Date],
StartOn,
EndOn,
ISNULL((
SELECT 1
FROM Data t2
WHERE t2.EmpId <> t1.EmpId
AND t2.[Date] = t1.[Date]
AND t2.StartOn < t1.EndOn
AND t2.EndON > t1.StartOn
), 0) As Overlapping
FROM Data t1
)
SELECT EmpId,
[Date],
StartOn,
EndOn,
Overlapping,
ISNULL(NULLIF(Overlapping, 0) + LAG(Overlapping) OVER (ORDER BY [Date], StartOn, EndOn), 0) As Num
FROM CTE
答案 2 :(得分:0)
我设法通过在分区
中添加iif
来解决它
;with overlapping as(
select a.EmpId,a.Date,a.StartOn,a.EndOn,count(b.EmpId) as Num
from #Data a
left join #Data b on a.Date = b.Date
and a.StartOn<=b.EndOn and a.EndOn>=b.StartOn and b.EmpId<>a.EmpId
group by a.EmpId,a.Date,a.StartOn,a.EndOn
)
select *,row_number() over(partition by Date,iif(Num=0,StartOn,Num) order by StartOn) as Row
from overlapping
order by Date,StartOn,EmpId
但我正在寻找更好的解决方案