PostgreSQL:通过与其他行比较筛选选择查询
假设我有一个事件表,其中列出了用户ID和事件发生的时间:PostgreSQL:通过与其他行比较筛选选择查询,sql,postgresql,select,filter,Sql,Postgresql,Select,Filter,假设我有一个事件表,其中列出了用户ID和事件发生的时间: +----+--------+----------------------------+ | id | userId | time | +----+--------+----------------------------+ | 1 | 46 | 2020-07-22 11:22:55.307+00 | | 2 | 190 | 2020-07-13 20:57:07.138+0
+----+--------+----------------------------+
| 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 |
+----+--------+----------------------------+
如何执行select查询,通过对照表中的其他行计算结果来筛选结果?您可以使用lag:
他是一把小提琴
或行号:
您可以使用lag:
他是一把小提琴
或行号:
这可以使用现有条件完成:
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
这可以使用现有条件完成:
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
可以使用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
可以使用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
您可以使用行数分析函数:
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
要为在多个事件中发生的用户ID带来最新事件。您可以使用行数分析功能:
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
为在多个事件中发生的用户ID带来最新事件。将其标记为正确,因为这是最简洁、最容易理解/适应的。我不能在现阶段评论性能。将其标记为正确,因为这是最简洁、最容易理解/改编的。在现阶段,我不能对表现发表评论。