查找最早但活跃的后续操作

时间:2017-10-15 13:58:15

标签: sql postgresql

我的表格如下:

+----+-----------+--------+------------------------+
| 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

3 个答案:

答案 0 :(得分: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小提琴。

答案 1 :(得分: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');

答案 2 :(得分: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'