当前位置:  开发笔记 > 数据库 > 正文

条件超前/滞后功能PostgreSQL?

如何解决《条件超前/滞后功能PostgreSQL?》经验,为你挑选了1个好方法。

我有这样一张桌子:

Name   activity  time

user1  A1        12:00
user1  E3        12:01
user1  A2        12:02
user2  A1        10:05
user2  A2        10:06
user2  A3        10:07
user2  M6        10:07
user2  B1        10:08
user3  A1        14:15
user3  B2        14:20
user3  D1        14:25
user3  D2        14:30

现在,我需要这样的结果:

Name   activity  next_activity

user1  A2        NULL
user2  A3        B1
user3  A1        B2

我想检查每个用户A组的最后一项活动以及接下来B组的活动类型(B组的活动总是在A组活动后进行).其他类型的活动对我来说并不感兴趣.我试过使用该lead()功能,但它没有奏效.

我怎么能解决我的问题?



1> Erwin Brands..:

测试设置:

CREATE TEMP TABLE t (name text, activity text, time time);
INSERT INTO t values
 ('user1', 'A1', '12:00')
,('user1', 'E3', '12:01')
,('user1', 'A2', '12:02')
,('user2', 'A1', '10:05')
,('user2', 'A2', '10:06')
,('user2', 'A3', '10:07')
,('user2', 'M6', '10:07')
,('user2', 'B1', '10:08')
,('user3', 'A1', '14:15')
,('user3', 'B2', '14:20')
,('user3', 'D1', '14:25')
,('user3', 'D2', '14:30');

你的定义:

B组的活动总是在A组活动后进行.

..逻辑上暗示在一个或多个A活动之后,每个用户有0或1个B活动.按顺序进行的活动不得超过1个.

你可以把它与一个窗口功能的工作,DISTINCT ON并且CASE,这应该是最快的方式很少每个用户行(见下文):

SELECT name
     , CASE WHEN a2 LIKE 'B%' THEN a1 ELSE a2 END AS activity
     , CASE WHEN a2 LIKE 'B%' THEN a2 END AS next_activity
FROM  (
   SELECT DISTINCT ON (name)
          name
        , lead(activity) OVER (PARTITION BY name ORDER BY time DESC) AS a1
        , activity AS a2
   FROM   t
   WHERE (activity LIKE 'A%' OR activity LIKE 'B%')
   ORDER  BY name, time DESC
   ) sub;

如果没有添加分支,则SQL CASE表达式默认为,所以我保持简短.NULLELSE

也假定time是定义的NOT NULL.否则,您可能想要添加NULLS LAST.为什么?

选择每个GROUP BY组中的第一行?

(activity LIKE 'A%' OR activity LIKE 'B%')activity ~ '^[AB]'旧版本的Postgres 更加冗长,但通常更快.关于模式匹配:

与PostgreSQL中的LIKE,SIMILAR TO或正则表达式匹配的模式

条件窗口函数?

这实际上是可能的.您可以将aggregate FILTER子句与OVERwindow函数的子句组合在一起.但是:

    FILTER条款本身只能从当前行值工作.

    更重要的是, FILTER没有实现像纯窗函数lead()lag()在Postgres的9.6(还) -仅适用于聚集函数.

如果你试试:

lead(activity) FILTER (WHERE activity LIKE 'A%') OVER () AS activity

Postgres会告诉你:

FILTER is not implemented for non-aggregate window functions

关于 FILTER:

如何简化此游戏统计查询?

引用窗口函数的FILTER子句中的当前行

性能

(对于少数用户每个用户行,几乎任何查询速度快,即使没有索引).

对于许多用户和每个用户行,上面的第一个查询应该是最快的.查看链接的答案上面关于索引和性能.

对于每个用户的许多行,有(可能更多)更快的技术,具体取决于您的设置的其他详细信息:

优化GROUP BY查询以检索每个用户的最新记录

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有