2017-03-01 27 views
0

我有一個表items它代表移動的項目。其中,該表中有PK name,其中包含了創建條目和字符串type的時間,這可以是startmoveendmove條目來插圖中startend時間戳creation_time通過額外的約束獲得連續時間戳中最大的區別?

表的一部分可能看起來像這樣:

name creation_time  type 
_________________________________ 
i1 2017-03-01 10:00:01 start 
i1 2017-03-01 10:00:02 move 
i1 2017-03-01 10:00:08 move 
i1 2017-03-01 10:00:10 end 
i1 2017-03-01 10:00:31 start 
i1 2017-03-01 10:00:33 move 
i1 2017-03-01 10:00:37 end 

我想要得到的是連續的時間戳的最大區別(S),其中第二時間戳的類型不是start(我不照顧endstart之間的時間)。

基於this SO question我來用下面的查詢這還沒有考慮到的條目類型:

select name, creation, next_creation, (next_creation-creation) difference from (
    select name, creation, (
    select min(creation) from items i2 
    where i2.name=i.name 
    and i2.creation > i.creation 
) as next_creation 
    from items i 
) 
where (next_creation-creation) is not null 
order by difference desc 

我的問題是,我不知道如何正確地過濾了現在鍵入。據我的理解,我必須從最內層的查詢中獲取類型,因爲我關心第二項的類型,然後將and type<>'start'添加到最外層查詢的where子句中 - 但我無法從中獲取兩個值子查詢,對嗎?

編輯:我希望是這樣的結果:

name creation   next_creation  difference action 
i1 2017-03-01 10:00:02 2017-03-01 10:00:08 6s   move 
i1 2017-03-01 10:00:33 2017-03-01 10:00:37 4s   end 
[...] 

正如你看到的,對於第一end和第二start之間的時間沒有進入,這就是要通過過濾來實現方式。

例如,在第一次和最後一次輸入之間的時間也沒有輸入,因爲我想要連續輸入之間的差異。

+0

請告訴我們查詢的最終結果應該是什麼樣子等。 –

+0

您需要每個名稱值的最大差異? – Mikhail

回答

2

要回答之前,其編輯的問題:

使用LAG analytic function

SELECT name, 
     MAX(time_difference) AS max_time_difference 
FROM (
    SELECT name, 
     type, 
     creation_time 
      - LAG(creation_time) OVER (PARTITION BY name ORDER BY creation_time) 
      AS time_difference 
    FROM items 
) 
WHERE type != 'start' 
GROUP BY name; 

更新

爲了得到它爲每個組開始/結束的項目(這似乎是你期望的輸出顯示 - 因爲它有多行):

SELECT name, 
     creation_time, 
     next_creation_time, 
     next_creation_time - creation_time AS difference, 
     type 
FROM (
    SELECT i.*, 
     ROW_NUMBER() OVER (
      PARTITION BY name, start_group 
      ORDER BY next_creation_time - creation_time DESC, creation_time ASC 
     ) AS rn 
    FROM (
    SELECT name, 
      type, 
      creation_time, 
      LEAD(creation_time) OVER (PARTITION BY name ORDER BY creation_time) 
      AS next_creation_time, 
      SUM(CASE type WHEN 'start' THEN 1 END) 
      OVER(PARTITION BY name ORDER BY creation_time) 
      AS start_group 
    FROM items 
) i 
    WHERE type != 'end' 
) 
WHERE rn = 1; 
+0

謝謝!該功能正是我所搜索的功能,而且我的建立的查詢速度更快。 –

0

根據我的理解。這必須包含子查詢中的「TYPE」列,可用作Inline View中的過濾器。希望能幫助到你。

SELECT name, 
    creation, 
    next_creation, 
    (next_creation-creation) difference 
FROM 
    (SELECT name, 
    creation, 
    (SELECT MIN(creation) 
    FROM items i2 
    WHERE i2.name =i.name 
    AND I2.CREATION > I.CREATION 
    ) AS NEXT_CREATION, 
    type 
    FROM items i 
) 
WHERE (NEXT_CREATION-CREATION) IS NOT NULL 
and type      <> 'start' 
ORDER BY difference DESC; 
0

如果你需要爲每個名稱值最大的區別,這樣的事情應該工作:

SELECT i1.NAME, MAX(i2.creation_time - i1.creation_time) difference 
FROM items i1 
INNER JOIN items i2 ON i1.name = i2.name AND i1.creation_time <= i2.creation_time 
WHERE 'start' NOT IN (i1.type, i2.type) 
GROUP BY i1.name;