2017-09-01 48 views
0

下表假設:SQL動態極限

user, timestamp, status_code 
1, 2017-08-21 09:03:50, 404 
2, 2017-08-21 09:03:48, 200 
1, 2017-08-21 09:03:45, 404 
1, 2017-08-21 09:03:42, 404 
1, 2017-08-21 09:03:41, 200 
1, 2017-08-21 09:03:40, 404 

如何選擇從用戶是404由200的該用戶的第一次出現有限的所有條目:

SELECT * FROM tbl WHERE user = 1 ORDER BY timestamp DESC ... ??? 

預期的結果:

user, timestamp, status_code 
1, 2017-08-21 09:03:50, 404 
1, 2017-08-21 09:03:45, 404 
1, 2017-08-21 09:03:42, 404 
+0

你能詳細解釋邏輯嗎?從預期的結果來看還不清楚。 –

+0

另外,您正在使用哪種RDBMS。 MySQL,Sql Server,Postgres等。? – JNevill

+0

爲什麼你不包括第一個記錄。它適用於同一個用戶,並在該用戶的200之後發生。 – JNevill

回答

0

使用子查詢:

SELECT tbl.* FROM tbl, 
    (SELECT user, MIN(timestamp) AS min_ts 
    FROM tbl 
    WHERE status_code = 200 
    GROUP BY user 
    ) AS subtable 
WHERE status_code = 404 
AND tbl.user = subtable.user 
AND tbl.timestamp > subtable.min_ts 
ORDER BY timestamp DESC 

http://sqlfiddle.com/#!9/bf725/3

+0

THis沒有得到條件獲得200行之前的所有行 – Alfabravo

+0

編輯答案(對不起,如果這是錯誤的方法) - 正如指出的那樣,我最初並沒有回答這個問題:時間戳過濾器。抱歉。 – meisen99

2

您可以使用相關子查詢來獲取這一點。

select * from tbl t1 
where timestamp > (select t2.timestamp 
        from tbl t2 
        where t1.user_id=t2.user_id and t2.status_code=200 
        order by t2.timestamp 
        limit 1) 
and status_code=404 
0

我理解你的查詢中尋找與狀態404,並早於狀態200爲同一用戶的任何行時間戳的所有行。

我想通過顛倒邏輯:嘗試將每個404行連接到狀態爲200的同一用戶的較早行,如果沒有找到,則404行是您想要的行選擇。當找不到這樣的行時,外連接將使連接行的所有列爲NULL。

select t1.* 
from tbl as t1 
left outer join tbl as t2 
    on t2.status_code = 200 
    and t1.user_id = t2.user_id 
    and t1.timestamp > t2.timestamp 
where t1.status_code = 404 
    and t2.user_id is NULL -- i.e. when the outer join finds no match 

上以該順序將有助於優化二者WHERE條件爲t1和T2的JOIN條件列(STATUS_CODE,USER_ID,時間戳)的索引。從邏輯上講,我的答案類似於Vamsi Prabhala的答案,但是我使用連接而不是相關的子查詢,所以我的應該更容易優化。