在 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
部分确保您还获得了结果集中的最新用户记录,因为显然它没有紧随其后的日期。
假设我们有一个具有以下架构的 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
部分确保您还获得了结果集中的最新用户记录,因为显然它没有紧随其后的日期。