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()
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)
输出
我有一个 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()
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)
输出