计算具有空值的最近连续行数
Count the most recent number of consecutive rows with a null value
我正在基于此演示设置在 PostgreSQL 10.6 中进行一些数据分析:
create table history (
registered_unix int,
requested_unix int,
alias character varying(255)
);
INSERT INTO history VALUES
(1537841388, 1537878224, '3')
, (1538093202, 1538095740, '1')
, (1538093186, 1538095740, '3')
, (1538105501, 1538107039, '2')
, (1538105501, 1538107039, '4')
, (1538205007, 1538242243, '2')
, (1538205012, NULL , '1')
, (1538105501, NULL , '1')
, (1538205007, NULL , '3')
, (1538105501, NULL , '3')
, (1538040863, NULL , '3')
, (1537985996, NULL , '3')
, (1538205007, NULL , '4')
, (1538093186, NULL , '4')
, (1538205301, NULL , '5')
, (1538105501, NULL , '5')
, (1538093186, NULL , '5');
我正在尝试计算 requested_unix
为空的连续 alias
行的数量,但仅针对第一次出现且连续出现大于或等于 2 的行数。
数据按别名排序,然后registered_unixDESC:
想要的结果:
别名 1:包括 b/c 它的 2 个最近的 "requested_unix" 值为空。
别名 2:已跳过。请求的 unix 在其最近的行上有一个值
别名 3:包括 b/c 它最近的 2 个 "requested_unix" 值为空。旧的被丢弃。
别名 4:已跳过。只有 1 个最新的 "requested_unix" 值为空。第二行有一个值。
别名 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<>fiddle here
在子查询中,每个 alias
和 DISTINCT ON (alias)
检索一行。 ORDER BY
使它成为我们需要的。
第一个 ORDER-BY 项目 alias
必须与 DISTINCT ON
一致。
第二个 ORDER-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
) window函数(在 DISTINCT ON
之前处理),并且您在单个查询级别中拥有所有必要的信息。外层的SELECT
只是为了assemble请求的结果格式。
相关:
- Select first row in each GROUP BY group?
- Sorting null values after all others, except special
- Best way to get result count before LIMIT was applied
我正在基于此演示设置在 PostgreSQL 10.6 中进行一些数据分析:
create table history (
registered_unix int,
requested_unix int,
alias character varying(255)
);
INSERT INTO history VALUES
(1537841388, 1537878224, '3')
, (1538093202, 1538095740, '1')
, (1538093186, 1538095740, '3')
, (1538105501, 1538107039, '2')
, (1538105501, 1538107039, '4')
, (1538205007, 1538242243, '2')
, (1538205012, NULL , '1')
, (1538105501, NULL , '1')
, (1538205007, NULL , '3')
, (1538105501, NULL , '3')
, (1538040863, NULL , '3')
, (1537985996, NULL , '3')
, (1538205007, NULL , '4')
, (1538093186, NULL , '4')
, (1538205301, NULL , '5')
, (1538105501, NULL , '5')
, (1538093186, NULL , '5');
我正在尝试计算 requested_unix
为空的连续 alias
行的数量,但仅针对第一次出现且连续出现大于或等于 2 的行数。
数据按别名排序,然后registered_unixDESC:
想要的结果:
别名 1:包括 b/c 它的 2 个最近的 "requested_unix" 值为空。
别名 2:已跳过。请求的 unix 在其最近的行上有一个值
别名 3:包括 b/c 它最近的 2 个 "requested_unix" 值为空。旧的被丢弃。
别名 4:已跳过。只有 1 个最新的 "requested_unix" 值为空。第二行有一个值。
别名 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<>fiddle here
在子查询中,每个 alias
和 DISTINCT ON (alias)
检索一行。 ORDER BY
使它成为我们需要的。
第一个 ORDER-BY 项目
alias
必须与DISTINCT ON
一致。第二个 ORDER-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
) window函数(在 DISTINCT ON
之前处理),并且您在单个查询级别中拥有所有必要的信息。外层的SELECT
只是为了assemble请求的结果格式。
相关:
- Select first row in each GROUP BY group?
- Sorting null values after all others, except special
- Best way to get result count before LIMIT was applied