我正在开发一个汇总财务数据观察的数据库(以货币对USDCAD为例)。
财务数据以观察结果的形式出现。我没有设置观察的日期和时间,因为它是由数据提供者决定的。
我的表看起来像这样:
CREATE TABLE observations (symbol varchar(32) not null, datetime datetime not null, value decimal(20, 10) not null);
当我需要在没有特定观察的时候获得系列的值时,问题就出现了。例如,我可能希望在上午10:30:15重新定价我们以加元购买的某种产品。
然而,我可能不会在上午10:30:15准备好USDCAD观察。这将要求我进行加权平均以在那个确切的时间进行观察。
这有点麻烦,但可能。更大的问题是 - 如果我每秒钟都有一张包含我们产品的美元价格的表格,并且我想重新定价USDCAD中的每个产品价格观察(每秒)(其中有随机定时观察),我不能想一想没有疯狂子查询的方法。
这里我最好的选择是什么?在插入值时,是否更好地计算USDCAD系列的每秒钟观测值?
答案 0 :(得分:3)
@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;
使用最新汇率以CAD价格创建VIEW
您的产品:
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
的引用替换为使用{{1动态构建此类表的子查询}}:
UNION