MySQL数据的规范化DateTime

MySQL数据的规范化DateTime,mysql,normalization,Mysql,Normalization,我正在开发一个汇总财务数据观察结果的数据库(以货币对USDCAD为例) 财务数据以观察值的形式出现。我没有设置观察的日期和时间,因为它是由数据提供者确定的 我的桌子看起来像这样: CREATE TABLE observations(符号varchar(32)不为null,datetime datetime不为null,值decimal(20,10)不为null) 当我需要在没有具体观察的时候得到序列的值时,问题就出现了。例如,我可能想对我们在上午10:30:15以加元销售的某种产品重新定价 但是

我正在开发一个汇总财务数据观察结果的数据库(以货币对USDCAD为例)

财务数据以观察值的形式出现。我没有设置观察的日期和时间,因为它是由数据提供者确定的

我的桌子看起来像这样:
CREATE TABLE observations(符号varchar(32)不为null,datetime datetime不为null,值decimal(20,10)不为null)

当我需要在没有具体观察的时候得到序列的值时,问题就出现了。例如,我可能想对我们在上午10:30:15以加元销售的某种产品重新定价

但是,我可能不会在上午10:30:15进行USDCAD观察。这将需要我做一个加权平均,以便在准确的时间得到观测值

这有点麻烦,但也是可能的。更大的问题是,如果我有一个表,每秒钟包含我们产品的美元价格,并且我想在USDCAD中重新定价每一个产品价格观察值(每秒钟)(存在随机计时的观察值),我想不出一种没有疯狂子查询的方法来做到这一点

我最好的选择是什么?在插入值时,是否也应计算USDCAD系列的每秒观测值

  • @时间
    通过应用以下方法获得加权平均观测值:


  • 更新

    要获得多个预定义时间的插值价格(假定存储为
    时间
    表中名为
    时间
    的列中的
    日期时间
    值),您需要使用子查询,首先获取紧靠前一个和紧靠后一个观测值的时间,然后再次将这些时间与观测值表合并,以获取相应的值:

    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`);
    

    在where条件下使用mysql时间(您的列)使用时间范围如何?嘿,不确定这是如何解决问题的。如何实现时间加权平均值(列)?到目前为止,您尝试了哪些方法?如果你写过任何查询,请把它挂起来,这样我们就可以看看如何解决它。我并没有真正的书面查询。。我有点希望得到一些信息……你们有什么样的数据吗??请把它放上去,非常感谢。我真的很喜欢1),它非常清晰,非常有用!唯一的补充是,我今天发现我需要对数据进行线性插值,而不考虑重新定价的事情。例如,假设我随机分散了1:04、1:12、1:17、1:21和1:27的观测值-我需要将数据显示为具有1:00、1:05、1:10、1:15、1:20、1:25、1:30的观测值,并插入相应的数据。您的查询正是这样做的,但只针对一个值。有没有办法在一个查询中对多个值执行此操作?再次感谢,再次感谢!您的查询非常有效。只有一件事我搞不懂,那是因为我简化了我的问题。在我的观测表中,我有一个名为series_id的列。这表示观测所属的系列,并且系统在该表中有许多不同系列的观测。我只需要在一个序列上执行上述操作,因此我尝试在连接的所有on子句中添加和series_id=id,但查询只会永远运行,永远不会返回。。我目前在表中有30000个观察值。我做错了什么?事实上-查询确实有效,只有查询需要10分钟才能完成!!发生了什么事?@user1094786:你在
    series\u id
    上有索引吗?@user1094786:就是这样,在最左边的列中有
    series\u id
    ?如果是这样的话,我想您还有另一个单独的索引,在最左边的列中有
    datetime
    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`;
    
    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`);
    
    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`);