sqlite - 忽略 lag/lad 中的空值
Posted
技术标签:
【中文标题】sqlite - 忽略 lag/lad 中的空值【英文标题】:sqlite - ignore nulls in lag/lad 【发布时间】:2021-02-14 16:09:45 【问题描述】:我使用 sqlite 并有两个表。第一个包含一系列无间隙的日期(下面的表 datelist),第二个包含日期和值(表:valuelist)。第二张表在日期系列中有空白。结果,我希望有一个无间隙的时间序列值。如果对于给定的一天 valuelist 中没有值,我假设那一天之前的最后一个值 NULL 是最好的近似值。
使用我的 SQL,我可以生成下表。 SQL 位于较大的表 (10^4) 和可能较大的间隙 (~100) 上,这是可以理解的,性能不佳。
lag(value, 100), ..., lag(value, 1) 的合并至少不优雅。 (不知道有没有用)
问题:有没有更高效(和优雅)的方式在 SQLite 中编写它?在其他 SQL 俚语中,窗口函数中有一个 IGNORE NULLS。 SQLites 似乎没有它们。 Window Functions 的 FILTER 部分也起作用 - lag 不是聚合函数。不能使用 max() 左右 - 值没有排序。
SELECT * FROM
(
SELECT d.dDate AS dDate, v.vDate
, julianday(d.dDate) - julianday(v.vDate) AS diff
, min(julianday(d.dDate) - julianday(v.vDate)) OVER (PARTITION BY d.dDate) AS min_diff
, v.value
FROM datelist AS d
LEFT OUTER JOIN valuelist AS v
ON d.dDate >= v.vDate
AND julianday(d.dDate) - JULIANDAY(v.vDate) < 30
order by d.dDate DESC, v.vDate
)
WHERE diff = min_diff
dDate | vDate | diff | min_diff | value | comment |
---|---|---|---|---|---|
2021-02-10 | 2021-02-09 | 1.0 | 1.0 | 6 | gap - value from 09-02 |
2021-02-09 | 2021-02-09 | 0.0 | 0.0 | 6 | |
2021-02-08 | 2021-02-08 | 0.0 | 0.0 | 7 | |
2021-02-07 | 2021-02-04 | 3.0 | 3.0 | 3 | gap - value from 04-02 |
2021-02-06 | 2021-02-04 | 2.0 | 2.0 | 3 | gap - value from 04-02 |
2021-02-05 | 2021-02-04 | 1.0 | 1.0 | 3 | gap - value from 04-02 |
2021-02-04 | 2021-02-04 | 0.0 | 0.0 | 3 | |
2021-02-03 | 2021-02-02 | 1.0 | 1.0 | 4 | gap - value from 02-02 |
2021-02-02 | 2021-02-02 | 0.0 | 0.0 | 4 | |
2021-02-01 | 2021-02-01 | 0.0 | 0.0 | 3 |
DROP TABLE IF EXISTS datelist;
CREATE TABLE datelist (dDate text);
INSERT INTO datelist values('2021-02-01');
INSERT INTO datelist values('2021-02-02');
INSERT INTO datelist values('2021-02-03');
INSERT INTO datelist values('2021-02-04');
INSERT INTO datelist values('2021-02-05');
INSERT INTO datelist values('2021-02-06');
INSERT INTO datelist values('2021-02-07');
INSERT INTO datelist values('2021-02-08');
INSERT INTO datelist values('2021-02-09');
INSERT INTO datelist values('2021-02-10');
DROP TABLE IF EXISTS valuelist;
CREATE TABLE valuelist(vDate text, value int );
INSERT INTO valuelist values('2021-02-01', 3);
INSERT INTO valuelist values('2021-02-02', 4);
INSERT INTO valuelist values('2021-02-04', 3);
INSERT INTO valuelist values('2021-02-08', 7);
INSERT INTO valuelist values('2021-02-09', 6);
【问题讨论】:
【参考方案1】:一个简单的方法是使用lead()
来获取值表的范围。然后将结果连接在一起:
select d.*, v.value
from datelist d left join
(select v.*, lead(vdate) over (order by vdate) as next_vdate
from valuelist v
) v
on d.dDate >= v.vDate and
(d.dDate < v.next_vdate or v.next_vdate is null);
Here 是一个 dbfiddle。
【讨论】:
将其重写为我的原始问题,它完全符合我的要求 :-) 谢谢!有趣的事实:我之前使用相同的想法来找出间隙的长度。我很难复杂...最后很容易:-) - 确定序列中间隙的长度: SELECT lag(vdate) OVER (ORDER BY vdate) , vdate , julianday(vdate) - julianday(lag(vdate ) OVER (ORDER BY vdate)) AS gap_length FROM valuelist ORDER BY gap_length以上是关于sqlite - 忽略 lag/lad 中的空值的主要内容,如果未能解决你的问题,请参考以下文章
如何忽略 PostgreSQL 窗口函数中的空值?或返回列中的下一个非空值
Linux/bash 解析文本输出,选择字段,仅忽略一个字段中的空值