T-SQL单个列的开始和结束日期时间

时间:2011-10-03 16:37:31

标签: sql sql-server tsql

我有一张不同资产的开/关事件表。我需要一个开始和放大的列表不使用游标停止事件时间。

来源:

Item      EventDate               Event
A         2011-10-03 00:01:00     On
B         2011-10-03 00:01:00     On
A         2011-10-03 00:02:00     Off
C         2011-10-03 00:01:00     On
B         2011-10-03 00:02:00     Off
A         2011-10-03 00:02:02     On      
C         2011-10-03 00:02:05     On
A         2011-10-03 00:02:07     Off

期望的结果:

Item      Start                   End
A         2011-10-03 00:01:00     2011-10-03 00:02:00
A         2011-10-03 00:02:02     2011-10-03 00:02:07
B         2011-10-03 00:01:00     2011-10-03 00:01:00
C         2011-10-03 00:01:00     2011-10-03 00:02:05

3 个答案:

答案 0 :(得分:1)

这是解决方案,每个人都需要验证概念验证。

我注意到Off的{​​{1}}事件被标记为新的C。我解决了这个问题,但这也促使我编写了一个解决方案,允许一个已经开始但尚未完成的事件,所以我包含了一个开放式事件On

此外,我的解决方案适用于重叠时段。

D

<强>解释

我们将数据集分为2个:declare @YourTable table (Item varchar(10), EventDate datetime, Event varchar(10)) insert into @YourTable values ('A', '2011-10-03 00:01:00', 'On'), ('B', '2011-10-03 00:01:00', 'On'), ('A', '2011-10-03 00:02:00', 'Off'), ('C', '2011-10-03 00:01:00', 'On'), ('B', '2011-10-03 00:02:00', 'Off'), ('A', '2011-10-03 00:02:02', 'On'), ('C', '2011-10-03 00:02:05', 'Off'), ('A', '2011-10-03 00:02:07', 'Off'), ('D', '2011-10-03 00:02:02', 'On') select tOn.Item, tOn.EventDate Start, tOff.EventDate [End] from ( select Item, EventDate, ROW_NUMBER() Over(Partition by Item order by EventDate) EventID from @YourTable where Event = 'On' ) tOn LEFT JOIN ( select Item, EventDate, ROW_NUMBER() Over(Partition by Item order by EventDate) EventID from @YourTable where Event = 'Off' ) tOff on (tOn.Item = tOff.Item and tOn.EventID = tOff.EventID) 个事件和On个事件。每个都包含一个编号的行,在Off更改时重新启动。

基本上,我们有先进先出:第一个Item将被第一个On关闭,因此此查询将支持重叠的时段做法。因此,Off的每个On事件都会显示A,并且会与通讯人Event ID Off相关联。

Event ID支持开放结束时段。

答案 1 :(得分:1)

未经测试...

;WITH myCTE AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY Item ORDER BY EventDate) AS rn
   FROM MyTable
)
SELECT
   M1.Item,
   M1.EventDate AS Start,
   M2.EventDate AS End
FROM
   myCTE M1
   JOIN
   myCTE M2 ON M1.Item = M2.Item AND M1.rn+1 = M2.rn
WHERE
   M1.Event = 'On'
   AND
   M2.Event = 'Off';

答案 2 :(得分:0)

declare @YourTable table (Item varchar(10), EventDate datetime, Event varchar(10)) 

insert into @YourTable values 
('A','2011-10-03 00:01:00''On'), 
('B','2011-10-03 00:01:00','On'), 
('A','2011-10-03 00:02:00','Off'), 
('C','2011-10-03 00:01:00','On'), 
('B','2011-10-03 00:02:00','Off'), 
('A','2011-10-03 00:02:02','On'),   
('C','2011-10-03 00:02:05','Off'), 
('A','2011-10-03 00:02:07','Off'), 
('D','2011-10-03 00:02:02','On')   

;with a as
(
select item, eventdate, event, ROW_NUMBER() Over(Partition by Item order by EventDate) RN 
from @YourTable
),
b as (
select item, eventdate, 0 e, rn, event from a where rn = 1
union all
select b.item, a.eventdate, case when b.event = 'Off' then b.e+1 else b.e end, a.rn, a.event
from b 
join a on b.rn + 1 = a.rn and a.item = b.item
)
select item, min(eventdate) Start, max(eventdate) [End]
 from b
group by item, e
order by item, e