窗口中的第一个和最后一个值在一行中函数 PostgreSQL

我希望在一行中具有相同列的第一个值和第二列的最后一个值为指定分区。 为此,我创建了此查询:


SELECT DISTINCT
b.machine_id,
batch,
timestamp_sta,
timestamp_stp,
FIRST_VALUE/timestamp_sta/ OVER w AS batch_start,
LAST_VALUE/timestamp_stp/ OVER w AS batch_end
FROM db_data.sta_stp AS a
JOIN db_data.ll_lu AS b
ON a.ll_lu_id=b.id
WINDOW w AS /PARTITION BY batch, machine_id ORDER BY timestamp_sta/
ORDER BY timestamp_sta, batch, machine_id;


但是,正如您在图像中看到的那样,列中的返回数据 batch_end 不必要。

柱子

batch_start 有正确的第一个含义

柱子 timestamp_sta. 但

batch_end

它应该是 "2012-09-17 10:49:45", 他是平等的

timestamp_stp

来自同一条线。

为什么这么做?

https://i.stack.imgur.com/h3DuF.png
已邀请:

知食

赞同来自:

这个问题很旧,但这个解决方案比到目前为止发布的更容易和更快:


SELECT b.machine_id
, batch
, timestamp_sta
, timestamp_stp
, min/timestamp_sta/ OVER w AS batch_start
, max/timestamp_stp/ OVER w AS batch_end
FROM db_data.sta_stp a
JOIN db_data.ll_lu b ON a.ll_lu_id = b.id
WINDOW w AS /PARTITION BY batch, b.machine_id/ -- No ORDER BY !
ORDER BY timestamp_sta, batch, machine_id; -- why this ORDER BY?


如果你补充说

ORDER BY


到窗口框架的定义,然后每个下一行都具有大表达式
ORDER BY

将稍后开始框架。 然后是n。
min//

, 我们
first_value//

将无法返回 "first" timestamp 对于整个部分。 没有
ORDER BY

同一部分的所有线条都是

一个范围

, 你得到了预期的结果。

你补充了
ORDER BY


在职的

/不是确定窗口框架的那个,而是一个外部/, 但似乎,它没有意义,并使要求更昂贵。 你应该使用该报价
ORDER BY

, 这与您的窗口框定义一致,以避免额外的排序成本:


... 
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;


我没有看到需要
DISTINCT

在此查询中。 如果真的需要,你可以添加它。 或者
DISTINCT ON //

. 但那么优惠
ORDER BY

它变得更加相关。 看:

https://coderoad.ru/3800551/
如果您需要其他一列/S./ 来自同一条线 /同时,仍然按时间邮票排序/, 你的想法S.
FIRST_VALUE//


LAST_VALUE//

可能是正确的解决方案。

然后

您可能必须将此添加到窗口框架的定义中 :


ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING


看:

https://dba.stackexchange.com/a/9800/3684

江南孤鹜

赞同来自:

解释,数据 @Łukasz Kamiński, 决定问题的本质。


last_value

应该被替换
max//

. 你排序
timestamp_sta

, 因此,最后一个值是具有最大值的值。
timestamp_sta

, 可以连接或无关
timestamp_stp

. 另外,我会分类两个领域。


SELECT DISTINCT
b.machine_id,
batch,
timestamp_sta,
timestamp_stp,
FIRST_VALUE/timestamp_sta/ OVER w AS batch_start,
MAX/timestamp_stp/ OVER w AS batch_end
FROM db_data.sta_stp AS a
JOIN db_data.ll_lu AS b
ON a.ll_lu_id=b.id
WINDOW w AS /PARTITION BY batch, machine_id
ORDER BY timestamp_sta,timestamp_stp
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING/
ORDER BY timestamp_sta, batch, machine_id;


http://rextester.com/UTDE60342

江南孤鹜

赞同来自:


https://www.postgresql.org/doc ... TIONS
:

Frame_clause 指定构成窗口帧的一组字符串,该窗口是当前分区的子集,用于在帧上采用帧的窗口函数,而不是在整个分区上。 帧可以设置为模式 RANGE 或者 ROWS; 在任何情况下,它都是从 frame_start 到 frame_end.

如果是参数 frame_end 省略,默认情况下使用当前行

.

Frame_start 无限前面意味着框架以相同的方式与部分的第一行开始 frame_end 无限的下一个意味着帧以截面的最后一行结尾。


https://www.postgresql.org/doc ... .html
last_value/value any/ 返回在字符串中计算的值

窗口框架的最后一串

如此正确 SQL 肯定是:


SELECT DISTINCT
b.machine_id,
batch,
timestamp_sta,
timestamp_stp,
FIRST_VALUE/timestamp_sta/ OVER w AS batch_start,
LAST_VALUE/timestamp_stp/ OVER w AS batch_end
FROM db_data.sta_stp AS a
JOIN db_data.ll_lu AS b
ON a.ll_lu_id=b.id
WINDOW w AS /PARTITION BY batch, machine_id ORDER BY timestamp_sta range between unbounded preceding and unbounded following/
ORDER BY timestamp_sta, batch, machine_id;

要回复问题请先登录注册