根据此演示设置,我正在PostgreSQL 10.6中进行一些数据分析:
create table history (
registered_unix int,
requested_unix int,
alias character varying(255)
);
insert into history values (1537841388,1537878224,'3');
insert into history values (1538093202,1538095740,'1');
insert into history values (1538093186,1538095740,'3');
insert into history values (1538105501,1538107039,'2');
insert into history values (1538105501,1538107039,'4');
insert into history values (1538205007,1538242243,'2');
insert into history values (1538205012,NULL,'1');
insert into history values (1538105501,NULL,'1');
insert into history values (1538205007,NULL,'3');
insert into history values (1538105501,NULL,'3');
insert into history values (1538040863,NULL,'3');
insert into history values (1537985996,NULL,'3');
insert into history values (1538205007,NULL,'4');
insert into history values (1538093186,NULL,'4');
insert into history values (1538205301,NULL,'5');
insert into history values (1538105501,NULL,'5');
insert into history values (1538093186,NULL,'5');
我试图计算连续的alias
行的数量,其中requested_unix
为空,但仅对于第一次出现且连续出现的次数大于或等于2的情况。
数据是按别名排序,然后是registered_unix DESC:
所需结果:
别名1:包含在b / c中,它的2个最近的“ requested_unix”值是空的。
别名2:已跳过。所请求的Unix在其最新行上具有一个值
别名3:包含在b / c中,它的2个最近的“ requested_unix”值是空的。较旧的将被丢弃。
别名4:已跳过。仅具有1个最新的“ requested_unix”值,该值为null。第二行有一个值。
别名5:已包含。 3个连续的最近值均为空。
有各种类型的票证可以统计连续出现的次数或找到第一个出现的次数,但似乎我想将两种方法结合起来。
使用DISTINCT ON
,我们只需要一个子查询:
SELECT alias
, CASE WHEN requested_unix IS NULL THEN ct ELSE rn - 1 END AS missed
, CASE WHEN requested_unix IS NULL THEN NULL ELSE registered_unix END AS last_success
, most_recent
FROM (
SELECT DISTINCT ON (alias)
*
, row_number() OVER (PARTITION BY alias ORDER BY registered_unix DESC) AS rn
, count(*) OVER (PARTITION BY alias) AS ct
, max(registered_unix) OVER (PARTITION BY alias) AS most_recent
FROM history h
ORDER BY alias, requested_unix IS NULL, registered_unix DESC
) latest_success
WHERE (requested_unix IS NULL OR rn > 2);
db <>小提琴here
在子查询中,每个alias
和DISTINCT ON (alias)
检索一行。 ORDER BY
使它成为我们需要的一个。
第一个ORDER-BY项目alias
必须与DISTINCT ON
一致。
第二个BYDER-BY项目requested_unix IS NULL
在顶部排序非空值。 (FALSE
在TRUE
之前排序。)requested_unix IS NOT NULL DESC
可能更直观,但我更喜欢短代码。
第3个ORDER-BY项目registered_unix DESC
在其中选择最新行。
具有窗口功能(在rn
之前处理)的每个分区添加行号(ct
),行数(registered_unix
)和最新的most_recent
(DISTINCT ON
),并且您拥有所有必要的信息在单个查询级别。外部的SELECT
只是用来组装请求的结果格式。
相关: