由id分隔的SQL分组由其他ID分隔

时间:2013-12-03 11:35:40

标签: sql-server sql-server-2008-r2 grouping

我使用的是MS SQL Server 2008 R2。 我有一张桌子:

    TypeId    EventDate                 Value      
1.  1         2013-11-01 10:13:00.000   50  
2.  1         2013-11-01 10:15:00.000   10  
3.  1         2013-11-01 10:18:00.000   40  
4.  2         2013-11-01 10:19:00.000   12  
5.  2         2013-11-01 10:21:00.000   545 
6.  1         2013-11-01 10:23:00.000   35  
7.  1         2013-11-01 10:27:00.000   47 
8.  3         2013-11-01 10:30:00.000   3
9.  4         2013-11-01 10:31:00.000   0
10. 4         2013-11-01 10:33:00.000   7
11. 4         2013-11-01 10:38:00.000   35
12. 1         2013-11-01 10:41:00.000   91 
13. 5         2013-11-01 10:45:00.000   37
14. 5         2013-11-01 10:48:00.000   35

我想要基于TypeId字段值的连续组,它们不被其他TypeId值分隔(当按EventDate排序时)。
在这个例子中,我希望有七个小组:

  • TypeId = 1,记录1-3
  • TypeId = 2,记录4-5
  • TypeId = 1,记录6-7
  • TypeId = 3,记录8
  • TypeId = 4,记录9-11
  • TypeId = 1,记录12
  • TypeId = 5,记录13-14

如果我使用GROUP BY TypeId,我会得到一个TypeId = 1的组,包括记录1-3,6-7和12

我想要为这些组中的任何一个获取min和max EventDate:

TypeId  MinEventDate              MaxEventDate
1       2013-11-01 10:13:00.000   2013-11-01 10:18:00.000
2       2013-11-01 10:19:00.000   2013-11-01 10:21:00.000
1       2013-11-01 10:23:00.000   2013-11-01 10:27:00.000
3       2013-11-01 10:30:00.000   2013-11-01 10:30:00.000
4       2013-11-01 10:31:00.000   2013-11-01 10:38:00.000
1       2013-11-01 10:41:00.000   2013-11-01 10:41:00.000
5       2013-11-01 10:45:00.000   2013-11-01 10:48:00.000

2 个答案:

答案 0 :(得分:1)

这是大数据集快速的替代方案。 CTE计算表示(EventDate)排序的行号与表示(TypeId, EventDate)排序的行号之间的差异,并调用差异grp。在每个连续的TypeId段中,差异将是恒定的,并且小于将为下一个连续TypeId段生成的差异。

然后,一组(TypeId, grp)包含具有相同状态的所有连续行:

; with  CTE as 
        (
        select  TypeId
        ,       EventDate
        ,       row_number() over (order by EventDate)
                    - row_number() over (order by TypeId, EventDate) as grp
        from     dbo.TestTable
        )
select  min(EventDate) as mn
,       max(EventDate) as mx
,       TypeId
from    CTE
group by 
        TypeId
,       grp
order by 
        mn;

See it working at SQLFiddle

有关此方法的详细信息,请参阅此sample chapter of MVP Deep Dives

答案 1 :(得分:0)

尝试此查询:

With T1 as 
(
select T.*,
 (select TOP 1 EventDate
  from Table1 where TypeID<>T.TypeId
                    and 
                    EventDate<T.EventDate
  ORDER BY EventDate DESC)
  as GrpStart
from Table1 as T
)
Select min(TypeId) as TypeId,
       min(EventDate) as MinEventDate,
       max(EventDate) as MaxEventDate
from T1 Group by GrpStart

SQLFiddle demo