如何将参数化的SQLITE查询应用于另一个查询返回的表的每一行(在插值的上下文中)?

时间:2016-05-26 11:09:43

标签: sql sqlite time-series interpolation

输入

我的输入包含 x_0_y_0 x_1

x_0_y_0 (表日期)包含表单的日期和值:

timestamp   value
2000-01-01  1
2000-01-03  3
2000-01-05  5

x_1 (查询 dates_to_interpolate )包含表单的日期:

timestamp
2000-01-01
2000-01-02
2000-01-03
2000-01-04
2000-01-05

输出

我想要的输出 x_1_y1 (查询 interpolation_results )的形式如下:

timestamp    value
2000-01-01   1
2000-01-02   2
2000-01-03   3
2000-01-04   4
2000-01-05   5

方法(尝试)

this主题和一些原生sqlite语法中使用信息我设法得到一个查询,该查询为单个选定日期提供插值(例如 4 ),例如' 2000年1月4' 日即可。

SELECT CASE WHEN next.timestamp IS NULL  THEN prev.value
            WHEN prev.timestamp IS NULL  THEN next.value
            WHEN next.timestamp = prev.timestamp  THEN prev.value
              ELSE ( ( julianday(date('2000-01-04')) - julianday(prev.timestamp) ) * next.value
                +    ( julianday(next.timestamp) - julianday(date('2000-01-04')) ) * prev.value
                   ) / (julianday(next.timestamp) - julianday(prev.timestamp))
       END AS interpolated_value 
FROM 
(SELECT dates.timestamp, dates.value FROM dates WHERE dates.timestamp <= date('2000-01-04') ORDER BY dates.timestamp DESC LIMIT 1) AS prev
CROSS JOIN 
(SELECT dates.timestamp, dates.value FROM dates WHERE dates.timestamp >= date('2000-01-04') ORDER BY dates.timestamp ASC LIMIT 1) AS next

现在我想使用 @interpolation_date 而不是'2000-01-04'对此进行参数化,所以我有一个 interpolated_value()形式的函数即可。如果我以编程方式调用它(例如来自Python或MATLAB),这似乎可行。问题是我想使用sqlite语法(在单个查询中)将interpolated_value()应用于 dates_to_interpolate 。我发现sqlite不支持视图中的参数,它不支持自定义函数。我确实看到了实现循环的尝试(我想我可能需要这里);循环似乎涉及递归触发器 WITH 语法,我不太熟悉。

1 个答案:

答案 0 :(得分:0)

你想要这样的东西:

SELECT timestamp,
       (...) AS value
FROM x1;

这可以通过使另一个查询成为相关子查询来完成,即只需将'2000-01-04'替换为x1.timestamp,无论它出现在何处:

SELECT timestamp,
       (SELECT CASE WHEN next.timestamp IS NULL  THEN prev.value
                    WHEN prev.timestamp IS NULL  THEN next.value
                    WHEN next.timestamp = prev.timestamp  THEN prev.value
                      ELSE ( ( julianday(x1.timestamp) - julianday(prev.timestamp) ) * next.value
                        +    ( julianday(next.timestamp) - julianday(x1.timestamp) ) * prev.value
                           ) / (julianday(next.timestamp) - julianday(prev.timestamp))
               END AS interpolated_value 
        FROM 
        (SELECT dates.timestamp, dates.value FROM dates WHERE dates.timestamp <= x1.timestamp ORDER BY dates.timestamp DESC LIMIT 1) AS prev
        CROSS JOIN 
        (SELECT dates.timestamp, dates.value FROM dates WHERE dates.timestamp >= x1.timestamp ORDER BY dates.timestamp ASC LIMIT 1) AS next
       ) AS value
FROM x1;