【发布时间】:2015-12-17 16:01:45
【问题描述】:
我需要根据当前记录的其他一些列和前一条记录的 X 值来计算某些列 X 的值(使用一些分区和顺序)。基本上我需要在表单中实现查询
SELECT <some fields>,
<some expression using LAG(X) OVER(PARTITION BY ... ORDER BY ...) AS X
FROM <table>
这是不可能的,因为只有现有的列可以在窗口函数中使用,所以我正在寻找解决这个问题的方法。
这是一个例子。我有一张有活动的桌子。每个事件都有type 和time_stamp。
create table event (id serial, type integer, time_stamp integer);
我不想找到“重复”事件(跳过它们)。重复是指以下内容。让我们按time_stamp 升序排列给定type 的所有事件。那么
- 第一个事件不是重复的
- 所有不重复且在其后某个时间范围内的事件(即它们的
time_stamp不大于前一个不重复的time_stamp加上一些常量TIMEFRAME)都是重复的 - 下一个
time_stamp比上一个不重复的事件大于TIMEFRAME的下一个事件不重复 - 等等
对于这个数据
insert into event (type, time_stamp)
values
(1, 1), (1, 2), (2, 2), (1,3), (1, 10), (2,10),
(1,15), (1, 21), (2,13),
(1, 40);
TIMEFRAME=10 结果应该是
time_stamp | type | duplicate
-----------------------------
1 | 1 | false
2 | 1 | true
3 | 1 | true
10 | 1 | true
15 | 1 | false
21 | 1 | true
40 | 1 | false
2 | 2 | false
10 | 2 | true
13 | 2 | false
我可以根据上一个非重复事件的当前time_stamp 和time_stamp 计算duplicate 字段的值,如下所示:
WITH evt AS (
SELECT
time_stamp,
CASE WHEN
time_stamp - LAG(current_non_dupl_time_stamp) OVER w >= TIMEFRAME
THEN
time_stamp
ELSE
LAG(current_non_dupl_time_stamp) OVER w
END AS current_non_dupl_time_stamp
FROM event
WINDOW w AS (PARTITION BY type ORDER BY time_stamp ASC)
)
SELECT time_stamp, time_stamp != current_non_dupl_time_stamp AS duplicate
但这不起作用,因为LAG中无法引用计算的字段:
ERROR: column "current_non_dupl_time_stamp" does not exist.
那么问题来了:我可以重写这个查询来达到我需要的效果吗?
【问题讨论】:
-
我无法理解时间框架部分。特别是这部分:
the next event which time_stamp if greater than previous non duplicate by more than TIMEFRAME is not duplicate。时间框架是常数、字段还是计算? -
TIMEFRAME是一些常数。基本原理是,如果它在未跳过的前一个事件之后的给定时间范围内发生,我想跳过它。 -
您想要的输出包含时间戳 40,但您的示例数据集没有?你能澄清一下吗?
-
你是对的,这是一个错误。
标签: postgresql gaps-and-islands