@time
通过应用线性插值获得加权平均观测值:
SELECT p0.y + (UNIX_TIMESTAMP(@time)-p0.x) * (p1.y-p0.y) / (p1.x-p0.x)
FROM
(
SELECT `value` AS y
, UNIX_TIMESTAMP(`datetime`) AS x
FROM `observations`
WHERE `datetime` <= @time
ORDER BY `datetime` DESC
LIMIT 1
) p0,
(
SELECT `value` AS y
, UNIX_TIMESTAMP(`datetime`) AS x
FROM `observations`
WHERE `datetime` >= @time
ORDER BY `datetime` ASC
LIMIT 1
) p1;
VIEW
使用最新汇率以 CAD 价格创建您的产品:
CREATE VIEW `productsCAD` AS
SELECT `products`.*
, `products`.`price` * `exchange`.`value` AS `priceCAD`
FROM `products`
, (
SELECT `value`
FROM `observations`
ORDER BY `datetime` DESC
LIMIT 1
) AS `exchange`;
更新
要获得多个预定义时间的插值价格(假设存储为名为的表DATETIME
中的列中的值),您需要使用子查询首先获取前一个和紧随其后的观察时间,然后将这些时间与观察结果连接起来再次表以获取相应的值:time
times
SELECT time, p0.y + IFNULL((unixtime-p0.x) * (p1.y-p0.y) / (p1.x-p0.x), 0) AS value
FROM
(
SELECT
time,
UNIX_TIMESTAMP(`time`) AS `unixtime`,
MAX(UNIX_TIMESTAMP(`before`.`datetime`)) AS `prevTime`,
MIN(UNIX_TIMESTAMP( `after`.`datetime`)) AS `nextTime`
FROM
`times`
JOIN (SELECT `datetime` FROM `observations`)
AS `before` ON (`before`.`datetime` <= `time`)
JOIN (SELECT `datetime` FROM `observations`)
AS `after` ON ( `after`.`datetime` >= `time`)
GROUP BY `time`
) AS `matches`
JOIN (
SELECT
UNIX_TIMESTAMP(`datetime`) AS x,
`value` AS y
FROM `observations`
) AS p0 ON (p0.x = `matches`.`prevTime`)
JOIN (
SELECT
UNIX_TIMESTAMP(`datetime`) AS x,
`value` AS y
FROM `observations`
) AS p1 ON (p1.x = `matches`.`nextTime`);
如果要在查询中指定所需的时间(而不是使用预定义的表times
),请将对的引用替换为times
使用动态构建此类表的子查询UNION
:
SELECT time, p0.y + IFNULL((unixtime-p0.x) * (p1.y-p0.y) / (p1.x-p0.x), 0) AS value
FROM
(
SELECT
time,
UNIX_TIMESTAMP(`time`) AS `unixtime`,
MAX(UNIX_TIMESTAMP(`before`.`datetime`)) AS `prevTime`,
MIN(UNIX_TIMESTAMP( `after`.`datetime`)) AS `nextTime`
FROM
(
SELECT '2012-05-02 19:20:00' AS `time`
UNION ALL SELECT '2012-05-02 19:20:05'
UNION ALL SELECT '2012-05-02 19:20:10'
UNION ALL SELECT '2012-05-02 19:20:15'
-- etc.
) AS `times`
JOIN (SELECT `datetime` FROM `observations`)
AS `before` ON (`before`.`datetime` <= `time`)
JOIN (SELECT `datetime` FROM `observations`)
AS `after` ON ( `after`.`datetime` >= `time`)
GROUP BY `time`
) AS `matches`
JOIN (
SELECT
UNIX_TIMESTAMP(`datetime`) AS x,
`value` AS y
FROM `observations`
) AS p0 ON (p0.x = `matches`.`prevTime`)
JOIN (
SELECT
UNIX_TIMESTAMP(`datetime`) AS x,
`value` AS y
FROM `observations`
) AS p1 ON (p1.x = `matches`.`nextTime`);