我需要得到“生产”的总和。失败之间的事件'事件。这有点难以解释,所以让我们看看数据以及所需的结果。见下表。输入表也以底部的文本形式给出。
黄色项目是失败事件(代码100)。绿色项目是生产事件(代码200)。我需要在失败事件之间生成时间,如上表所示。请注意,上一个失败事件之后没有任何生产事件,因此需要忽略它。
我的猜测是Rank()函数会涉及某个地方,但我正在努力解决这个问题!
+---------------------+---------------------+-----------------+------------+-----------+
| StartDate | EndDate | DurationInHours | Equipment | EventCode |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-01 06:31:51 | 2014-01-01 09:14:57 | 2.7183 | Equipment1 | 100 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-01 09:17:20 | 2014-01-01 13:34:40 | 4.2889 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-01 21:59:49 | 2014-01-01 23:20:29 | 1.3444 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-03 22:23:33 | 2014-01-03 22:41:57 | 0.3067 | Equipment1 | 100 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-03 22:51:49 | 2014-01-04 05:48:43 | 6.9483 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-04 06:26:18 | 2014-01-04 14:04:20 | 7.6339 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-04 14:32:44 | 2014-01-04 18:07:29 | 3.5792 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-04 18:27:16 | 2014-01-04 22:40:37 | 4.2225 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-04 22:40:37 | 2014-01-04 23:13:15 | 0.5439 | Equipment1 | 100 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-04 23:13:15 | 2014-01-04 23:13:20 | 0.0014 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-04 23:13:26 | 2014-01-05 07:24:11 | 8.1792 | Equipment1 | 200 |
+---------------------+---------------------+-----------------+------------+-----------+
| 2014-01-05 07:24:11 | 2014-01-05 09:24:45 | 2.0094 | Equipment1 | 100 |
+---------------------+---------------------+-----------------+------------+-----------+
答案 0 :(得分:2)
这是另一种我认为会更有效的方法。不使用带有TOP(1)和ORDER BY的APPLY,这种方法使用LEAD()OVER()然后在这些日期边界内聚合。
请参阅此备选方案SQL Fiddle
查询1 :
select
t1.Equipment
, grp.StartDate
, grp.EndDate
, sum(t1.DurationInHours) sumDurationInHours
from table1 as t1
inner join (
select
t2.Equipment
, t2.StartDate
, lead(t2.EndDate) over(partition by t2.Equipment order by t2.EndDate) EndDate
from table1 as t2
where t2.eventcode = 100
) grp on t1.Equipment = grp.Equipment
and t1.StartDate between grp.StartDate and grp.EndDate
where t1.eventcode = 200
group by
t1.Equipment
, grp.StartDate
, grp.EndDate
<强> Results 强>:
| Equipment | StartDate | EndDate | sumDurationInHours |
|------------|----------------------|----------------------|--------------------|
| Equipment1 | 2014-01-01T06:31:51Z | 2014-01-03T22:41:57Z | 5.6333 |
| Equipment1 | 2014-01-03T22:23:33Z | 2014-01-04T23:13:15Z | 22.3853 |
| Equipment1 | 2014-01-04T22:40:37Z | 2014-01-05T09:24:45Z | 8.1806 |
答案 1 :(得分:1)
我测试了这个 我希望它符合你的要求。
Create table test(STARTDATE datetime, enddate datetime, eventcode int)
insert into test
Select '2017-01-01 06:31:51', '2017-01-01 09:14:51' ,100 union all
Select '2017-01-01 10:31:51', '2017-01-01 11:14:51' ,200 union all
Select '2017-01-01 12:31:51', '2017-01-01 15:15:51' ,200 union all
Select '2017-01-01 17:21:51', '2017-01-01 18:14:51' ,100 union all
Select '2017-01-01 19:31:51', '2017-01-01 19:51:51' ,200 union all
Select '2017-01-01 20:11:51', '2017-01-01 21:14:51' ,100 union all
Select '2017-01-01 22:31:51', '2017-01-01 23:14:51' ,200
with cte as
(
Select ROW_NUMBER() over( order by startdate) rn, * From test Where
eventcode = 100
)
Select a.STARTDATE as failuredate,
cast(datediff(mi,a.STARTDATE, b.STARTDATE)as varchar(10)) DiffInMinutes
from cte a
left join cte b on a.rn+1 = b.rn
只需将DiffInMinutes转换为hh:mm。
答案 2 :(得分:1)
您可以使用APPLY(多次),其中一个apply的别名可以在下一个中使用。请注意,此方法可能不适合大型表格。
看到它在这里工作MS SQL Server 2014架构设置:
CREATE TABLE Table1
([StartDate] datetime, [EndDate] datetime, [DurationInHours] decimal(12,4), [Equipment] varchar(10), [EventCode] int)
;
INSERT INTO Table1
([StartDate], [EndDate], [DurationInHours], [Equipment], [EventCode])
VALUES
('2014-01-01 06:31:51', '2014-01-01 09:14:57', 2.7183, 'Equipment1', 100),
('2014-01-01 09:17:20', '2014-01-01 13:34:40', 4.2889, 'Equipment1', 200),
('2014-01-01 21:59:49', '2014-01-01 23:20:29', 1.3444, 'Equipment1', 200),
('2014-01-03 22:23:33', '2014-01-03 22:41:57', 0.3067, 'Equipment1', 100),
('2014-01-03 22:51:49', '2014-01-04 05:48:43', 6.9483, 'Equipment1', 200),
('2014-01-04 06:26:18', '2014-01-04 14:04:20', 7.6339, 'Equipment1', 200),
('2014-01-04 14:32:44', '2014-01-04 18:07:29', 3.5792, 'Equipment1', 200),
('2014-01-04 18:27:16', '2014-01-04 22:40:37', 4.2225, 'Equipment1', 200),
('2014-01-04 22:40:37', '2014-01-04 23:13:15', 0.5439, 'Equipment1', 100),
('2014-01-04 23:13:15', '2014-01-04 23:13:20', 0.0014, 'Equipment1', 200),
('2014-01-04 23:13:26', '2014-01-05 07:24:11', 8.1792, 'Equipment1', 200),
('2014-01-05 07:24:11', '2014-01-05 09:24:45', 2.0094, 'Equipment1', 100)
;
查询1 :
select
t1.startdate, ca1.nextend, ca2.sumDurationInHours
from table1 as t1
cross apply (
select top(1) EndDate as nextend
from table1 as t2
where t2.StartDate > t1.StartDate and t2.EventCode = 100
order by t2.StartDate
) ca1
cross apply (
select sum(DurationInHours) as sumDurationInHours
from table1 as t3
where t3.StartDate >= t1.StartDate
and t3.EndDate < ca1.nextend
and t3.EventCode = 200
) ca2
where t1.eventcode = 100
<强> Results 强>:
| startdate | nextend | sumDurationInHours |
|----------------------|----------------------|--------------------|
| 2014-01-01T06:31:51Z | 2014-01-03T22:41:57Z | 5.6333 |
| 2014-01-03T22:23:33Z | 2014-01-04T23:13:15Z | 22.3839 |
| 2014-01-04T22:40:37Z | 2014-01-05T09:24:45Z | 8.1806 |