规范化MySQL数据的日期时间

时间:2012-05-02 05:19:52

标签: mysql normalization

我正在开发一个汇总财务数据观察的数据库(以货币对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系列的每秒钟观测值?

1 个答案:

答案 0 :(得分:3)

  1. 通过应用linear interpolation

    ,在@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;
    
  2. 使用最新汇率以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`;
    

  3. <强>更新

    要获取多个预定义时间的插值价格(假设在名为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