我的数据集中的公司每天都有时间序列并使用PostgreSQL 对于每个公司,应删除column3中所有NULL为空的行,直到此公司的此列中的第一个NOT NULL条目为止。然后,使用NOT NULL的该公司的最后一个可观察值的值填充所有连续缺失值。
您可以想象以下示例数据:
date company column3
1 2004-01-01 A 5
2 2004-01-01 B NULL
3 2004-01-01 C NULL
4 2004-01-02 A NULL
5 2004-01-02 B 7
6 2004-01-02 C NULL
7 2004-01-03 A 6
8 2004-01-03 B 7
9 2004-01-03 C 9
10 2004-01-04 A NULL
11 2004-01-04 B NULL
12 2004-01-04 C NULL
如果我设法编写一个提供
的查询,那就太好了 date company column3
1 2004-01-01 A 5
2 2004-01-02 A 5
3 2004-01-02 B 7
4 2004-01-03 A 6
5 2004-01-03 B 7
6 2004-01-03 C 9
7 2004-01-04 A 6
8 2004-01-04 B 7
9 2004-01-04 C 9
我试过了:
SELECT a.date, a.company, COALESCE(a.column3, (SELECT b.column3 FROM mytable b
WHERE b.company=a.company AND b.colmun3 IS NOT NULL ORDER BY b.company=a.company
DESC LIMIT 1)) FROM mytable a;
代码存在两个问题:
答案 0 :(得分:1)
尝试:
SELECT *
FROM (
SELECT id,
date,
company,
case when column3 is not null
then column3
else (
SELECT column3
FROM mytable t1
WHERE t1.company = t.company
AND t1.date < t.date
AND t1.column3 IS NOT NULL
ORDER BY t1.date DESC LIMIT 1
)
end column3
FROM mytable T
) AS subq
WHERE column3 IS NOT NULL;
答案 1 :(得分:1)
我建议使用两个子查询级别window functions而不是相关的子查询:
SELECT *
FROM (
SELECT the_date, company, max(col3) OVER (PARTITION BY company, grp) AS col3
FROM (
SELECT *, count(col3) OVER (PARTITION BY company ORDER BY the_date) AS grp
FROM tbl
) sub1
) sub2
WHERE col3 IS NOT NULL
ORDER BY the_date, company;
生成请求的结果。
这假定每(company, the_date)
个唯一条目。对于只有几行的表,应该快得多。一个(唯一来强制执行唯一性?!)索引将有助于提高性能:
CREATE INDEX tbl_company_date_idx ON tbl (company, the_date);
聚合函数count()
在计数时忽略NULL值。用作聚合窗函数,它根据默认窗口定义RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
计算列的运行计数。这导致计数对具有NULL值的行“卡住”,从而形成共享相同(非空)值的对等组。
在第二个窗口函数中,使用max()
可以轻松提取每个组的唯一非空值。第一个非null值之前的组保留NULL,这在最终的SELECT中很容易消除。
在这个密切相关的答案中有更多解释:
Retrieve last known value for each column of a row