计算具有空值的最近连续行数

问题描述 投票:2回答:1

根据此演示设置,我正在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

enter image description here

所需结果:

enter image description here

别名1:包含在b / c中,它的2个最近的“ requested_unix”值是空的。

别名2:已跳过。所请求的Unix在其最新行上具有一个值

别名3:包含在b / c中,它的2个最近的“ requested_unix”值是空的。较旧的将被丢弃。

别名4:已跳过。仅具有1个最新的“ requested_unix”值,该值为null。第二行有一个值。

别名5:已包含。 3个连续的最近值均为空。

有各种类型的票证可以统计连续出现的次数或找到第一个出现的次数,但似乎我想将两种方法结合起来。

sql postgresql greatest-n-per-group window-functions gaps-and-islands
1个回答
1
投票

使用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

在子查询中,每个aliasDISTINCT ON (alias)检索一行。 ORDER BY使它成为我们需要的一个。

  • 第一个ORDER-BY项目alias必须与DISTINCT ON一致。

  • 第二个BYDER-BY项目requested_unix IS NULL在顶部排序非空值。 (FALSETRUE之前排序。)requested_unix IS NOT NULL DESC可能更直观,但我更喜欢短代码。

  • 第3个ORDER-BY项目registered_unix DESC在其中选择最新行。

具有窗口功能(在rn之前处理)的每个分区添加行号(ct),行数(registered_unix)和最新的most_recentDISTINCT ON),并且您拥有所有必要的信息在单个查询级别。外部的SELECT只是用来组装请求的结果格式。

相关:

© www.soinside.com 2019 - 2024. All rights reserved.