SQL 按时间分组

SQL Group by timing

我有一个 table,它有一个我想作为分组依据的列,但只有它的最后一个系列(table 有一个时间戳列可以使用)例如table

Type | Time
=============
A    | 1:00
A    | 1:05
B    | 1:10
C    | 1:15
A    | 1:20
A    | 1:25
A    | 1:30

我想将它们分组以对它们执行函数(Sum()、Max()、Avg()),并且只在分组被破坏之前获取分组,因此按类型的标准分组将不起作用。

我想要这样的东西:

Type | count_in_series | MinTime
================================
A    | 2               | 1:00
B    | 1               | 1:10
C    | 1               | 1:15
A    | 3               | 1:20

无法知道变化何时发生,给出的数据只是为了说明这一点的示例。

这可能吗?

解决方案

我将其与以下答案中的概念结合使用。事实证明我正在使用的程序不允许变量或 WITH CTE。这是我使用子查询的解决方案:

SELECT 
    Type
    , max(t_stamp) as maxTime
    , min(t_stamp) as minTime
FROM
    (SELECT
        *
        , ROW_NUMBER() OVER (ORDER BY t_stamp desc) - ROW_NUMBER() OVER (PARTITION BY Type ORDER BY t_stamp desc) as grouping
    FROM MyTable) as t1
GROUP BY t1.grouping, t1.Type
ORDER BY min(t_stamp) desc

像这样的东西应该可以工作:

SELECT 
  Type,
  count('Type'),
  min('Time')
FROM table
GROUP BY Type

----- 已编辑 ------
Check this SQL fiddle
如果您可以使用用户变量,那就行得通了:

SET @typeIndex = 1;

SELECT
  min(type) as type,
  count(type) as count,
  min(TIME_FORMAT(time, '%H %i')) as minTime
FROM(
  SELECT
  t.type, 
  t.time,
  (SELECT type FROM timeTest tt
        WHERE tt.time < t.time
        ORDER BY time DESC LIMIT 1) as next_type,
  IF(type != (SELECT type FROM timeTest tt
        WHERE tt.time < t.time
        ORDER BY time DESC LIMIT 1), @typeIndex := @typeIndex+1, "" ) as t ,
  @typeIndex as tipeIndex
  FROM 
    timeTest t
) temp
GROUP BY temp.tipeIndex

您可以使用滞后和 row_number 来获得正确的桶,然后按如下方式进行分组:

;with cte as (
select *, Bucket = sum(sm) over (order by RowN) from (
select *,sm = case when (lag(type,1) over (order by [time]) <> [type]) then 1 else 0 end, 
    RowN= row_number() over(order by [time]) from #yourtime 
    ) a
    )
    select min([Type]) as [Type], count([Type]) as Count_in_Series, min([time]) as MinTime  from cte
    group by Bucket

你的输出:

+------+-----------------+------------------+
| Type | Count_in_Series |     MinTime      |
+------+-----------------+------------------+
| A    |               2 | 01:00:00.0000000 |
| B    |               1 | 01:10:00.0000000 |
| C    |               1 | 01:15:00.0000000 |
| A    |               3 | 01:20:00.0000000 |
+------+-----------------+------------------+

您的输入table:

create table #yourtime (type varchar(2), [Time] time)

insert into #yourtime ([type], [time]) values
 ('A','1:00')
,('A','1:05')
,('B','1:10')
,('C','1:15')
,('A','1:20')
,('A','1:25')
,('A','1:30')

如果您没有 LAG,您可以只使用 ROW_NUMBER()

SQL DEMO

With CTE AS (
    SELECT T.*,           
           ROW_NUMBER() OVER (ORDER BY [TIME]) as ID,
           ROW_NUMBER() OVER (PARTITION BY [Type] ORDER BY [TIME]) as rn
    FROM Table1 T       
)
SELECT [Type], COUNT(*) Count , MIN(Time) Time
FROM CTE
GROUP BY [Type], ID - rn
ORDER BY MIN(Time)

输出