2013-08-16 79 views
2

我有一個與datestamps事件表,我想顯示事件之間的時間間隔。舉例來說,如果我有計算記錄之間的時間?

event | datestamp 
------------------- 
    a | 05:00 
    b | 07:00 
    c | 08:00 
    d | 12:00 
... 

我想編寫一個簡單的查詢,讓我

event | datestamp | last | since_last 
----------------------------------------- 
    a | 05:00  | NULL | NULL 
    b | 07:00  | a | 2 hours 
    c | 08:00  | b | 1 hour 
    d | 12:00  | c | 4 hours 

最後一列的格式並不重要 - 它可以是毫秒,秒,東西人類可讀,無論簡單。另外請注意,實際的數據有適當的日期,我只是懶得輸入日期。

重要的是,在記錄中沒有指向「a」作爲前一個事件的「b」,所以像in this question這樣的解決方案不起作用 - 我需要一些語法來選擇所有記錄加入最近的較舊記錄。

我已經試過看起來像

SELECT new.event, new.datestamp, old.event AS last, 
    TIMESTAMPDIFF(SECOND, MAX(old.datestamp), new.datestamp) AS since_last 
FROM events AS new, events AS old 
WHERE new.datestamp > old.datestamp 
LIMIT 10; 

,但它只是似乎掛起 - 我讓它運行超過一分鐘。每this question,我試圖

SELECT event, datestamp, 
    (SELECT MAX(old.datestamp) 
    FROM events old 
    WHERE new.datestamp > old.datestamp 
) last_ds 
FROM events new 
LIMIT 10; 

這實際工作,但需要在我的表超過14秒,一萬個事件,即使我只選擇10個記錄,所以一定出事了。

+1

你選擇10條記錄,但內部查詢有做計算你的百萬+的記錄。 – ApplePie

+0

如果你想要你的最後10條記錄是不可能通過時間戳限制你的內部查詢到最後10條記錄? – Prix

+0

人。給定一條記錄,我知道如何編寫一個查詢,用於「選擇日期戳記的最小值小於myrecord.datestamp」的記錄,並且該查詢將立即返回。我想我需要以某種方式「嵌套」,而不是? – Coderer

回答

3

嘗試使用

select event,datestamp, 
     @PrevEvent as last, 
     TIMESTAMPDIFF(SECOND, @PrevDate, datestamp) AS since_last, 
     @PrevDate:=datestamp, 
     @PrevEvent:=event 
from events, (select @PrevDate:=null,@PrevEvent:=null) t 
order by datestamp 

SQLFiddle demo

要選擇最後10個事件只是使用子查詢與LIMIT而不僅僅是events表。

select event,datestamp, 
     @PrevEvent as last, 
     TIMESTAMPDIFF(SECOND, @PrevDate, datestamp) AS since_last, 
     @PrevDate:=datestamp, 
     @PrevEvent:=event 
from (select * 
     from events 
     order by datestamp DESC 
     LIMIT 10 
    ) t1, (select @PrevDate:=null,@PrevEvent:=null) t 
order by datestamp 

UPD:

要在10最近得到正確的第一行(不爲NULL since_last場)應先在內部子查詢LIMIT 11(10 + 1),然後在外部查詢LIMIT 10 OFFSET 1

select event,datestamp,last,since_last 
FROM 
(
select event,datestamp, 
     @PrevEvent as last, 
     TIMESTAMPDIFF(SECOND, @PrevDate, datestamp) AS since_last, 
     @PrevDate:=datestamp, 
     @PrevEvent:=event 
from (select * 
     from events 
     order by datestamp DESC 
     LIMIT 11 
    ) t1, (select @PrevDate:=null,@PrevEvent:=null) t 
order by datestamp 
) t3 
LIMIT 10 offset 1 
+0

前2列有點多餘,但否則應該起作用。 – Vatev

+0

此解決方案快速有效,但我不確定如何更改它以查看最近的事件而不是最舊的事件。請注意,我有一百萬個事件,而且我主要關心最近的事件。 – Coderer

+0

@Coderer我已經添加了一個查詢來選擇最近的記錄。 – valex

1
Select event,datestamp,last,since_last FROM 
(select event,datestamp, 
     @PrevEvent as last, 
     concat((TIMESTAMPDIFF(SECOND, @PrevDate, datestamp))/3600, 
       ' Hours') AS since_last, 
     @PrevDate:=datestamp, 
     @PrevEvent:=event 
from events, (select @PrevDate:=null,@PrevEvent:=null) t 
order by datestamp) abc 

Fiddle

+0

巧妙地使用嵌套選擇來隱藏來自變量賦值的多餘值。您也可以從選擇中刪除'event'和'datestamp',並用'(@PrevDate:= datestamp)AS datestamp'替換'@PrevDate:= datestamp'等。列的順序是錯誤的,真的不重要。 – Coderer

相關問題