2017-05-08 156 views
1

我有有,我想组一个列的表,但只有最后一个系列的它(该表有一个时间戳列一起工作)例如表SQL集团通过定时

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 
+3

您正在使用哪个数据库管理系统? SQL Server?甲骨文? – GurV

+0

窗口函数如果引擎支持它,Lead()可以帮助您。如果不是,则可以使用用户变量并分配行号并加入row_number + 1 = rowNumber,然后将T1.Type与T2.Type进行比较,当不同的重置计数时相同的加计数。 – xQbert

+0

@GurwinderSingh通过点火客户端SQL express – Evan

回答

1

如果你没有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) 

输出

enter image description here

+1

我正在使用的客户端不允许使用变量或WITH CTE,但使用您的概念我想出了一个使用子查询的解决方案。谢谢你,看我的问题编辑为我使用的解决方案 – Evan

0

像这样的东西应该工作:-------
Check this SQL fiddle

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 
+2

不完全是:在预期结果中看看2个“A”。基本上算直到类型改变,然后重新计数。并显示每个组的最短时间。 – xQbert

+0

对不起,我错过了,然后检查这个小提琴:http://sqlfiddle.com/#!9/eb22c9/29。 – Cyrus

+0

我正在使用的客户端不允许使用变量或WITH CTE,但我想出了一个使用子查询的解决方案。谢谢,看我的问题编辑为我使用的解决方案 – Evan

1

您可以使用lag和row_number获得正确的桶,然后做组p通过如下:

;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 | 
+------+-----------------+------------------+ 

您的输入表:

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') 
+0

为什么你没有使用使用'OVER(按[时间]命令)? –

+0

我喜欢把输入顺序存储在表中,因为我们需要延迟的顺序 –

+0

db表是无序的数据集,除非包含'ORDER BY',例如索引和分区,否则**不能保证顺序可以给你不同的结果,因为数据的存储方式不同。 –