SQL查询-根据条件对连续项进行分组

SQL查询-根据条件对连续项进行分组,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我不知道这个问题叫什么名字。如果标题与问题不符,请原谅。我有生产和计划外维护事件的数据,按设备和时间顺序排列。见下表,见问题底部的文本版本: 应根据指示的颜色对数据进行分组,并对持续时间列进行汇总。结果见下文。基本上,计划外维护时间应与生产时间相加,直到出现新的计划外维护事件,从而分组 我已经能够通过使用非常复杂的排名和加入程序来完成一些事情,但是完成50万条记录需要一个小时,这非常缓慢。我需要一个5分钟内就能用的东西。请注意,我不能使用lead或lag函数,因为需要执行查询的服务器使用的是较旧

我不知道这个问题叫什么名字。如果标题与问题不符,请原谅。我有生产和计划外维护事件的数据,按设备和时间顺序排列。见下表,见问题底部的文本版本:

应根据指示的颜色对数据进行分组,并对持续时间列进行汇总。结果见下文。基本上,计划外维护时间应与生产时间相加,直到出现新的计划外维护事件,从而分组

我已经能够通过使用非常复杂的排名和加入程序来完成一些事情,但是完成50万条记录需要一个小时,这非常缓慢。我需要一个5分钟内就能用的东西。请注意,我不能使用lead或lag函数,因为需要执行查询的服务器使用的是较旧版本的SQL server 2008

结果应该是这样的:

任何帮助都将不胜感激

包含大量数据的表格create语句可在此处下载:

起始日期=力矩

忽略结束日期列

+---------------------+-----------+-----------+-------------------------+
| Moment              | Duration  | Equipment | DowntimeType            |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 08:34:03 | 2.734444  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 11:39:26 | 0.015833  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 11:41:23 | 0.4925    | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 12:10:56 | 0.679444  | DT46      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 12:51:42 | 0.628888  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 15:23:48 | 0.650833  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 16:05:19 | 3.341111  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-14 19:44:01 | 7.292777  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-15 03:18:15 | 5.954722  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-15 09:50:54 | 3.899722  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-15 19:33:11 | 1.760277  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-15 21:18:48 | 0.637222  | DT46      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-15 21:57:02 | 3.109722  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-16 01:14:15 | 4.128611  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-16 18:33:01 | 0.004166  | DT46      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-16 19:19:38 | 2.580833  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-17 01:23:56 | 0.111388  | DT46      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-17 01:30:37 | 0.293333  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-17 01:48:13 | 0.99      | DT46      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-17 03:26:10 | 3.805833  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2014-07-17 07:14:49 | 1.435833  | DT46      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-28 01:18:43 | 1.283611  | DT63      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-28 02:47:50 | 0.224166  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-28 03:17:09 | 7.085277  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-28 11:12:14 | 2.519722  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-28 18:36:54 | 3.239166  | DT63      | Unscheduled Maintenance |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-29 03:20:04 | 1.735833  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-29 05:07:52 | 8.631944  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-29 23:53:44 | 6.074444  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-11-30 23:04:51 | 14.720555 | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-12-02 01:06:50 | 0.001111  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
| 2015-12-02 01:07:28 | 4.540277  | DT63      | Production              |
+---------------------+-----------+-----------+-------------------------+
我想

1为计划外维护分配序列号

2找出两个非计划维护值之间的生产值。通过对上限和下限使用相同的子查询

3根据上限的q1力矩对持续时间和组进行求和。

检查此项

select min(StartDate) 'Moment',min(Equipment) 'Equipment',sum(Duration) 'Total Duration' from mytable a
cross apply (select top 1 b.StartDate from mytable b where b.StartDate>a.StartDate and b.[DowntimeType]='Unscheduled Maintenance' order by StartDate asc) sq1(nextMaintenance)
group by nextMaintenance
order by min(StartDate)
试试这个分组

select min(Moment), Equipment, sum(duration)
from (
  select *,
    case DowntimeType when 'Unscheduled Maintenance' 
      then row_number() over(partition by Equipment, DowntimeType order by Moment) 
      else row_number() over(partition by Equipment order by Moment) - row_number() over(partition by Equipment, DowntimeType order by Moment) end r
   from myTable
) t
where r > 0 -- must start with 'Unscheduled Maintenance' 
group by Equipment, r
order by Equipment, r

我们可以看看您尝试了哪些代码吗?如此复杂的问题几乎肯定需要一些测试。出于对我们的礼貌,我认为您至少应该提供CREATETABLE语句,或者更好的是提供一个演示。您的sql server版本是什么。你能用over来运行sum吗?我已经添加了一个链接,指向带有table的sql table create语句,以及sql versionI不能复制你的Google文档。创建一个Rextester演示:感谢您的帮助-我相信您的查询可以正常工作,但是我无法运行它,因为它花费了太长的时间来执行
select min(Moment), Equipment, sum(duration)
from (
  select *,
    case DowntimeType when 'Unscheduled Maintenance' 
      then row_number() over(partition by Equipment, DowntimeType order by Moment) 
      else row_number() over(partition by Equipment order by Moment) - row_number() over(partition by Equipment, DowntimeType order by Moment) end r
   from myTable
) t
where r > 0 -- must start with 'Unscheduled Maintenance' 
group by Equipment, r
order by Equipment, r