2017-05-08 136 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',例如索引和分區,否則**不能保證順序可以給你不同的結果,因爲數據的存儲方式不同。 –