SQL按时间分组

SQL按时间分组,sql,sql-server-express,Sql,Sql Server Express,我有一个表,它有一个我想要分组的列,但是只有它的最后一个系列,表有一个时间戳列,例如表 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 | M

我有一个表,它有一个我想要分组的列,但是只有它的最后一个系列,表有一个时间戳列,例如表

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
没有办法知道什么时候会发生变化,给出的数据只是一个例子来说明这一点

这可能吗

解决方案

我使用了下面答案中的概念。结果证明我使用的程序不允许变量或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
---编辑---- 如果可以使用用户变量,则可以:

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

您可以使用lag和row_编号来获得正确的存储桶,然后按以下方式进行分组:

;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
您的输入表:

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')
如果你没有延迟,你可以只使用行号

输出


您使用的是哪种数据库管理系统?SQL Server?如果引擎支持,Oracle?窗口功能主管可能会帮助您。如果不是,您可以使用用户变量并分配行号,然后在row_number+1=rowNumber上联接,然后将T1.Type与T2.Type进行比较。相同时键入,不同时添加计数。@GurwinderSingh SQL express通过点火客户端不完全:查看预期结果中的2 a。基本上计数,直到类型更改,然后重置计数。并显示每个组的最小时间。我使用的客户端不允许变量或CTE,但我提出了一个使用子查询的解决方案。谢谢,请参阅我的问题编辑,了解我使用的解决方案为什么您没有在[时间]之前使用过order?我喜欢按照输入顺序将其存储在表中,因为我们要求lagdb表的顺序是无序数据集,除非您包括order by,例如,索引和分区可以提供不同的结果,因为数据存储方式不同..是的,我知道。。这里的要求是保持第一个桶中的前两个A的顺序,然后是B、C和第四个桶中的下一个3 A的顺序,然后我们只能相应地进行最小和最大。。。如果我按时间下单,那么我们将失去这个订单,在实际场景中,他可能在那个专栏上有一个合适的订单,如果你按时间下单,你将获得OP所需的订单。前两个A,后三个A。现在你的答案是不确定的。因为可以根据db存储这些行的方式提供不同的结果。在OP没有提供订单的情况下,您应该要求提供订单。我使用的客户端不允许变量或CTE,但使用您的概念,我提出了使用子查询的解决方案。谢谢,请参见我使用的解决方案的问题编辑
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')
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)