0

我的问题是在derived_daily 表(从源表prices_daily 派生)中填充我的最后两列。

(源表)prices_daily:

sequence        INT(11)         NO    PRI  AUTO_INCREMENT
symbol          VARCHAR(6)      NO    MUL
date            DATE            NO    MUL
high            DECIMAL(8,2)    YES
low             DECIMAL(8,2)    YES
close_adj       DECIMAL(8,2)    YES

(目标表)derived_daily:

symbol           VARCHAR(6)     YES
date             DATE           NO
mov_avg10        DECIMAL(8,2)   YES
std_dev10        DECIMAL(8,2)   YES
range_daily      DECIMAL(8,2)   YES
range_std_dev30  DECIMAL(8,2)   YES

我可以使用以下代码填充前 4 列:

INSERT INTO derived_daily(symbol, date, mov_avg10, std_dev10)
(
SELECT t1.symbol, t1.date, AVG(t2.close_adj) AS mov_avg10, STDDEV(t2.close_adj) 
           AS std_dev10 
FROM prices_daily t1 LEFT OUTER JOIN prices_daily t2 
    ON t2.symbol = t1.symbol AND (t1.sequence - t2.sequence)BETWEEN 0 AND 9 
    WHERE t1.symbol = 'C' GROUP BY t1.date
) ; 

但是当我尝试在派生表中填充“range_daily”时:

INSERT INTO derived_daily(symbol, date, range_daily)
(
SELECT t2.symbol, t2.date, (high - low) AS range_daily 
FROM prices_daily t1 
LEFT OUTER JOIN derived_daily t2 
    ON t2.symbol = t1.symbol AND t2.date = t1.date 
    WHERE t2.symbol = 'C' 
    ORDER BY t2.date
) ; 

它将它放在正确的列中,但在新行的表底部,而不是带有缺失数据的现有行(range_daily 和最终,range_std_dev30)。我已经尝试了许多调整,并且大部分都得到“错误1364,字段'日期'没有默认值。我想填充最后两列以匹配我已经放置在表中的内容(相同行),而不是底部的新行。

我花了很长时间查看相关的问题/答案,但仍然无法与我的问题相关(菜鸟......道歉)。任何帮助/建议/等。将不胜感激!PS正在适当地格式化问题,但不得不来到主要位置(这个网站是顶部),因为我很沮丧哈哈。

谢谢,汤姆

4

1 回答 1

0

我认为您想要 UPDATE 现有行,而不是 INSERT 新行。

例如:

UPDATE ( SELECT t1.symbol
              , t1.date
              , AVG(t2.close_adj) AS mov_avg10
              , STDDEV(t2.close_adj) AS std_dev10
           FROM prices_daily t1
           LEFT
           JOIN prices_daily t2
             ON t2.symbol = t1.symbol
            AND (t1.sequence - t2.sequence) BETWEEN 0 AND 9
          WHERE t1.symbol = 'C'
          GROUP
             BY t1.symbol
              , t1.date
       ) s
  JOIN derived_daily t
    ON t.symbol = s.symbol
   AND t.date = s.date
   SET t.mov_avg10 = s.mov_avg10
     , t.std_dev10 = s.std_dev10

为了测试,您可以将UPDATE关键字替换为SELECT t.symbol, t.date, t.mov_avg10, t.std_dev10, s.mov_avg10, s.std_dev10 FROM并删除SET末尾的子句。这将列出 t 中将要更新的行、行中的现有值以及将分配的新值。


跟进

要插入所有列,您可以组合三个查询。这是一个怪物查询,但是一旦我们将它分解成它的组件,它就会变得有意义。

INSERT INTO derived_daily
( symbol
, `date`
, mov_avg10
, std_dev10
, range_daily
, range_std_dev30
)
SELECT q.symbol
     , q.date
     , q.mov_avg10
     , q.std_dev10
     , r.range_daily
     , s.range_std_dev30
  FROM ( SELECT t1.symbol
              , t1.date
              , AVG(t2.close_adj) AS mov_avg10
              , STDDEV(t2.close_adj) AS std_dev10
           FROM prices_daily t1
           LEFT
           JOIN prices_daily t2
             ON t2.symbol = t1.symbol
            AND (t1.sequence - t2.sequence) BETWEEN 0 AND 9
          WHERE t1.symbol = 'C'
          GROUP BY t1.symbol, t1.date
       ) q
  LEFT
  JOIN ( SELECT t3.symbol
              , t3.date
              , (t3.high - t3.low) AS range_daily
           FROM prices_daily t3
          WHERE t3.symbol = 'C'
       -- GROUP BY t3.symbol, t3.date
       ) r
    ON r.symbol = q.symbol
   AND r.date = q.date
  LEFT
  JOIN ( SELECT t4.symbol
              , t4.date
              , STDDEV(d.range_daily) AS range_std_dev30
           FROM prices_daily t4
           LEFT
           JOIN ( SELECT t5.symbol
                       , t5.date
                       , (t5.high - t5.low) AS range_daily
                    FROM prices_daily t5
                   WHERE t5.symbol = 'C'
                -- GROUP BY t5.symbol, t5.date
                ) d
             ON d.symbol = t4.symbol
            AND d.date >= t4.date
            AND d.date <= t4.date + INTERVAL -30 DAY
          WHERE t4.symbol = 'C'
          GROUP BY t4.symbol, t4.date
       ) s
    ON s.symbol = q.symbol
   AND s.date = q.date
 ORDER BY q.date, q.symbol

该查询本质上是以下形式

INSERT INTO target
SELECT q.key
     , q.val
     , r.val
     , s.val
  FROM q
  LEFT
  JOIN r ON r.key = q.key
  LEFT
  JOIN s ON s.key = q.key

这假设它(symbol,date)在(源)prices_daily表上是唯一的,并且在(目标)derived_daily表上也是唯一的。

为了测试,我们可以运行分别提供来自 q、r 和 s 的值的查询。

我对 range_std_dev30 ... STDDEV 的公式进行了一次拍摄,该公式是从当前日期到 30 天后的范围值。

(我有点担心使用 AUTO_INCREMENT 序列来派生过去的 10 行......我们通常不依赖于保证 auto_increment id 值将是连续的,没有间隙。这就是我们观察,但不能保证行为,特别是如果以不同的顺序插入行。

(对于 30 天,我使用了日期范围比较。)

于 2013-07-13T02:41:02.227 回答