在 sql 中有效地找到 "isolated" 行

Efficiently find "isolated" rows in sql

假设我们有一个具有以下架构的 table:

| ID            | DATE          | VALUE |
| ------------- |:-------------:| -----:|
| 1             | '2016-08-01'  |  1600 |
| 9             | '2016-03-03'  |    12 |
| 1             | '2016-08-21'  |     1 |
| 4             | '2016-09-01'  |     1 |
| ....                ....         .... |

如何高效地查找 table 在行的 DATE 后 N 天内不包含具有相同 ID 的记录的所有行?

简单地说,目标是为每个用户找到 "last action"(用户在 至少 N 天后没有任何操作)

我听起来很清楚:)

SELECT *
FROM mytable t1
WHERE NOT EXISTS (
    SELECT id 
    FROM mytable t2 
    WHERE 
        t2.date > t1.date AND 
        t2.date < t1.date + '30days'::interval AND 
        t1.id = t2.id
)

当然,您必须将语法(尤其是与日期相关的)与目标数据库相匹配。

您可以使用 lead window 函数。这将比使用 correlated 子查询执行得更好:

select *
from   ( select id, date, value,
                lead(date) over (partition by id order by date) next_date
         from   mytable ) as detail
where  date < date_sub(next_date, 30) or  next_date is null

这假定您的日期字段是时间戳。如果是字符串,则使用datediff.

请注意,next_date is null 部分确保您还获得了结果集中的最新用户记录,因为显然它没有紧随其后的日期。