PostgreSQL:通过与其他行进行比较来过滤选择查询

时间:2020-07-22 13:57:29

标签: sql postgresql select filter

假设我有一个事件表,其中列出了userId和事件发生的time

+----+--------+----------------------------+
| id | userId |            time            |
+----+--------+----------------------------+
|  1 |     46 | 2020-07-22 11:22:55.307+00 |
|  2 |    190 | 2020-07-13 20:57:07.138+00 |
|  3 |     17 | 2020-07-11 11:33:21.919+00 |
|  4 |     46 | 2020-07-22 10:17:11.104+00 |
|  5 |     97 | 2020-07-13 20:57:07.138+00 |
|  6 |     17 | 2020-07-04 11:33:21.919+00 |
|  6 |     17 | 2020-07-11 09:23:21.919+00 |
+----+--------+----------------------------+

我想获取同一用户在同一天发生过先前事件的事件列表。上表的结果将是:

+----+--------+----------------------------+
| id | userId |            time            |
+----+--------+----------------------------+
|  1 |     46 | 2020-07-22 11:22:55.307+00 |
|  3 |     17 | 2020-07-11 11:33:21.919+00 |
+----+--------+----------------------------+

如何执行选择查询,以通过对表中的其他行进行评估来过滤结果?

4 个答案:

答案 0 :(得分:1)

您可以使用lag()

select t.*
from (select t.*,
             lag(time) over (partition by userid, time::date order by time) as prev_time
      from t
     ) t
where prev_time is not null;

Here是db <>小提琴。

row_number()

select t.*
from (select t.*,
             row_number() over (partition by userid, time::date order by time) as seqnum
      from t
     ) t
where seqnum >= 2;

答案 1 :(得分:1)

这可以使用EXISTS条件完成:

select t1.*
from the_table t1
where exists (select *  
              from the_table t2
              where t2.userid = t1.userid -- for the same user
                and t2.time::date = t1.time::date -- on the same
                and t2.time < t1.time); -- but previously on that day

答案 2 :(得分:0)

您可以使用LAG()查找用户的上一行。然后,简单比较就能知道它是否在同一天发生。

例如:

select *
from (
  select
    *,
    lag(time) over(partition by userId order by time) as prev_time
  from t
) x
where date::date = prev_time::date

答案 3 :(得分:0)

您可以使用ROW_NUMBER()分析函数:

SELECT id , userId , time
  FROM
  (
   SELECT ROW_NUMBER() OVER (PARTITION BY UserId, date_trunc('day',time) ORDER BY time DESC) AS rn,
          t.*
     FROM Events
   ) q
 WHERE rn > 1 

以便为发生在多个事件中的UserId带来最新事件。

相关问题