2017-10-15 52 views
2

我的表看起來像這樣:尋找最古老的,但主動採取下列行動

+----+-----------+--------+------------------------+ 
| ID | type | userID |   time   | 
+----+-----------+--------+------------------------+ 
| 1 | FOLLOW |  1 | 2017-09-22 13:47:00+00 | 
| 2 | FOLLOW |  2 | 2017-09-22 13:48:00+00 | 
| 3 | FOLLOW |  3 | 2017-09-22 13:49:00+00 | 
| 4 | UNFOLLOW |  1 | 2017-09-22 13:50:00+00 | 
| 5 | UNFOLLOW |  3 | 2017-09-22 13:51:00+00 | 
| 6 | FOLLOW |  3 | 2017-09-22 13:52:00+00 | 
| 7 | FOLLOW |  4 | 2017-09-22 13:53:00+00 | 
| 8 | FOLLOW |  1 | 2017-09-22 13:54:00+00 | 
| 9 | UNFOLLOW |  2 | 2017-09-22 13:55:00+00 | 
+----+-----------+--------+------------------------+ 

它描述都遵循用戶已採取的行動。我正在嘗試編寫一個查詢,查詢中找到最舊但仍然有效的動作FOLLOW。主動意味着,之後沒有UNFOLLOW動作。我無法找到適用於單個查詢的解決方案。

在這個例子中,結果應該是第6行。

Fiddle with example data

+0

你想讓這個每個用戶ID?還是總體? –

+0

@GordonLinoff整體。在現實世界中,將會有另一列定義哪個用戶採取了這一行動。這只是StackOverflow的簡化版本。 – Timo

+0

。 。對我來說這似乎很奇怪,因爲「unfollow」是每個用戶,但結果是所有用戶。 –

回答

3

嗯。下面是使用not exists一個方法:

select distinct on (userId) t.* 
from t 
where not exists (select 1 
        from t t2 
        where t2.userId = t.userId and t2.type = 'UNFOLLOW' and 
         t2.time > t.time 
       ) and 
     t.type = 'FOLLOW' 
order by t.userId, t.time asc; 

這將返回每個用戶ID老積極的後續

編輯:

以上假定您希望爲每個用戶的信息 - 這對我來說很有意義。但是如果你想在一個最古老的,則:

select t.* 
from actions t 
where not exists (select 1 
        from actions t2 
        where t2.userId = t.userId and t2.type = 'UNFOLLOW' and t2.time > t.time 
       ) and 
     t.type = 'FOLLOW' 
order by t.time asc 
fetch first 1 row only; 

Here是SQL搗鼓這個版本。

0

此查詢將只檢索每個用戶的最新記錄,如果它是FOLLOW;

select * from actions where id in (
    select a.id from actions as a where 
    a.time = (select max(time) from actions where userid = a.userid) 
    and a.type = 'FOLLOW'); 
0
SELECT * 
FROM 
    (SELECT ID, Type, userID, rank() OVER(PARTITION BY userID ORDER BY fDate DESC) AS seqnum 
    FROM flw 

    ) T 
    WHERE seqnum = 1 AND 
    T.type <> 'UNFOLLOW'