我有一个进程记录事件发生的时间,并假设此事件在接下来的六个小时内有影响。
表格包含Date,Period,BooleanValue等数据;如果日是dd / mm / yyyy,则Period是值1-48,表示半小时(一天中有48个)以及事件是否已经发生(Impact或NotImpact)。例如,2011年1月5日(第3期)发生了单个事件,因此表格如下:
Date Period Event
05/01/2011 1 NotImpact
05/01/2011 2 NotImpact
05/01/2011 3 IMPACT
05/01/2011 4 NotImpact
05/01/2011 5 NotImpact
在Excel中,我创建了第四列并编写了一个公式,在“事件”列中查找“影响”,如果找到,则将接下来的12个半小时标记为“影响”。如果找不到“IMPACT”,则使用默认值“NotImpact”。
=IF(IF(ISERROR(COUNTIF(E2:E13,"IMPACT")),"NotImpact",COUNTIF(E2:E13,"DIS"))>0,"IMPACT","NotImpact")
将此公式应用于第四栏,结果如下:
Date Period Event ImpactYesNo
05/01/2011 1 NotImpact NotImpact
05/01/2011 2 NotImpact NotImpact
05/01/2011 3 IMPACT IMPACT
05/01/2011 4 NotImpact IMPACT
05/01/2011 5 NotImpact IMPACT
05/01/2011 6 NotImpact IMPACT
05/01/2011 7 NotImpact IMPACT
05/01/2011 8 NotImpact IMPACT
05/01/2011 9 NotImpact IMPACT
05/01/2011 10 NotImpact IMPACT
05/01/2011 11 NotImpact IMPACT
05/01/2011 12 NotImpact IMPACT
05/01/2011 13 NotImpact IMPACT
05/01/2011 14 NotImpact IMPACT
05/01/2011 15 NotImpact NotImpact
05/01/2011 16 NotImpact NotImpact
05/01/2011 17 NotImpact NotImpact
我更希望在SQL中生成此表(此表驻留在SQL Server 2005框中),并且我尝试在那里复制此Excel方法(并在Python中编写函数),但没有成功。如果有人可以帮助我或指出我正确的方向,我真的很感激。
如果我可以回答有关我的要求的任何其他问题,请不要犹豫,在评论中弹出它们
答案 0 :(得分:1)
DECLARE
@Intervals INT, -- How many periods per day
@Lasts INT -- Number of intervals effected
SELECT
@Intervals = 48,
@Lasts = 6
-- Use CTE to calculate continous sequence #
;WITH SeqImpact ([Date], Period, [Event], Seq)
AS (Select *, Convert(int, Date) * @Intervals + Period as SEQ from IMPACT)
SELECT
[Date],
Period,
[Event],
CASE (
SELECT Count(*)
FROM SeqImpact History
WHERE
History.Seq <= SeqImpact.Seq
AND History.Seq > SeqImpact.Seq - @Lasts
AND [Event] = 'Impact'
)
WHEN 0 THEN 'NotImpact'
ELSE 'Impact'
END
AS ImpactYesNo
FROM SeqImpact
答案 1 :(得分:0)
你可以试试这个。它会将您的日期和期间转换为日期时间,然后对其进行一些计算。您必须测试数据,看看性能是否足够好。
set dateformat dmy
;with C as
(
select dateadd(minute, (Period - 1) * 30, cast([Date] as datetime)) as StartTime,
[Date],
Period,
[Event]
from YourTable
)
select C1.[Date],
C1.Period,
C1.[Event],
coalesce(C2.[Event], C1.[Event]) as ImpactYesNo
from C as C1
left outer join (select StartTime,
dateadd(hour, 6, StartTime) as EndTime,
[Event]
from C
where [Event] = 'IMPACT') as C2
on C1.StartTime >= C2.StartTime and
C1.StartTime < C2.EndTime
order by C1.StartTime
答案 2 :(得分:0)
declare @T table
(
[Date] varchar(10),
Period int,
[Event] varchar(9)
);
-- shortened to 1 hour periods
insert into @T
select '20110501', 1, 'NotImpact' union all
select '20110501', 2, 'NotImpact' union all
select '20110501', 3, 'NotImpact' union all
select '20110501', 4, 'NotImpact' union all
select '20110501', 5, 'NotImpact' union all
select '20110501', 6, 'NotImpact' union all
select '20110501', 7, 'NotImpact' union all
select '20110501', 8, 'NotImpact' union all
select '20110501', 9, 'NotImpact' union all
select '20110501', 10, 'NotImpact' union all
select '20110501', 11, 'NotImpact' union all
select '20110501', 12, 'NotImpact' union all
select '20110501', 13, 'NotImpact' union all
select '20110501', 14, 'NotImpact' union all
select '20110501', 15, 'IMPACT' union all
select '20110501', 16, 'NotImpact' union all
select '20110501', 17, 'NotImpact' union all
select '20110501', 18, 'NotImpact' union all
select '20110501', 19, 'NotImpact' union all
select '20110501', 20, 'NotImpact' union all
select '20110501', 21, 'NotImpact' union all
select '20110501', 22, 'NotImpact' union all
select '20110501', 23, 'NotImpact' union all
select '20110501', 24, 'NotImpact' union all
select '20110601', 1, 'NotImpact' union all
select '20110601', 2, 'NotImpact' union all
select '20110601', 3, 'NotImpact' union all
select '20110601', 4, 'NotImpact' union all
select '20110601', 5, 'NotImpact' union all
select '20110601', 6, 'NotImpact' union all
select '20110601', 7, 'NotImpact' union all
select '20110601', 8, 'NotImpact' union all
select '20110601', 9, 'NotImpact' union all
select '20110601', 10, 'NotImpact' union all
select '20110601', 11, 'NotImpact' union all
select '20110601', 12, 'NotImpact' union all
select '20110601', 13, 'NotImpact' union all
select '20110601', 14, 'NotImpact' union all
select '20110601', 15, 'NotImpact' union all
select '20110601', 16, 'NotImpact' union all
select '20110601', 17, 'NotImpact' union all
select '20110601', 18, 'NotImpact' union all
select '20110601', 19, 'NotImpact' union all
select '20110601', 20, 'NotImpact' union all
select '20110601', 21, 'NotImpact' union all
select '20110601', 22, 'NotImpact' union all
select '20110601', 23, 'NotImpact' union all
select '20110601', 24, 'NotImpact';
with cte as
(
select [Date], Period, [Event],
ROW_NUMBER() OVER (ORDER BY [Date], Period) AS rn
from @T
)
SELECT
T1.[Date], T1.Period,
ISNULL(T2.[Event], T1.[Event]),
T1.rn , T2.rn
FROM
cte T1
LEFT JOIN
cte T2 ON T1.rn BETWEEN T2.rn AND T2.rn + 12 AND T2.[Event] = 'Impact'