如何将值(-1,0,1)分配给具有20列和20行的MySQL表中的连续行之间的差异

时间:2016-04-17 06:38:26

标签: mysql mysql-workbench

我有一个来自MySQL的表,名为References,有20列和20行:

CREATE TABLE bop_ppy 
( start_time DATETIME (6)
, end_time DATETIME (6)
, high DECIMAL (5,2)
, low DECIMAL  (5,2)
, close DECIMAL (5,2)
, vol DECIMAL (5,2)
, vol_avg DECIMAL (5,2)
, range_ DECIMAL (5,2)
, poc_ DECIMAL (5,2)
, va_h DECIMAL (5,2)
, va_l DECIMAL (5,2)
, va_range DECIMAL (5,2)
, tpot INT
, tpo_ab INT
, tpo_bl INT
, sf DECIMAL (5,2)
, tff DECIMAL (5,2)
, rf INT
, vty DECIMAL (5,2)
, dists INT).

数据每日更新。

我需要计算每列的连续行之间的差异,除了start_time和end_time列,它们增加1天),这样如果第2天的值高于第1天的值,我们分配+差异+1;如果第2天的值小于第1天的值,我们将-1分配给该差异;如果第2天的值等于第1天的值,我们将0分配给该差异。我们的想法是生成一个新的表/视图,只显示标签,而不是原始值。

每行对应一天的数据。 我正在使用MySQL Workbench。

我曾尝试首先对表进行自我连接,然后将虚拟变量分配给连续行之间的差异,但到目前为止这还没有奏效。我不知道如何让这个工作了。请有人帮忙。

2 个答案:

答案 0 :(得分:0)

通常它是由索引完成的,但由于您的数据每天都会更新,因此您可以使用日期。为此,您需要执行简单的嵌套选择。这样的事情可以做到:

Select start_time, high - (select distinct high from table as b where TO_DAYS(a.start_time)-TO_DAYS(b.start_time)=1) from table as a

这是一个很高的例子。随意推断。

这意味着,对于每一行,我们现在进行另一次选择,寻找时间差为一天的记录。然后我们获取该记录的值并将其与当前记录进行比较。

如果您需要翻转结果,只需将-1替换为-1。

答案 1 :(得分:0)

如果ORDER BY start_date将行添加到day1,day2订单中,并且您不关心处理两行具有相同start_date并且不关心start_date中的任何“间隙”的情况,那么这样的东西会返回你要找的+1,0,-1或NULL标签。在返回的第一行上,不会有要比较的前一行,因此这些行的所有diff_值都将为NULL。

SELECT d.start_date
     , d.diff_high
     , d.diff_low
     , d.diff_close
     , d.diff_vol
     , d.diff_vol_avg
     , d.diff_range_
     , d.diff_poc_
     , d.diff_va_h
     , d.diff_va_l
     , d.diff_va_range
     , d.diff_tpot
     , d.diff_tpo_ab
     , d.diff_tpo_bl
     , d.diff_sf
     , d.diff_tff
     , d.diff_rf
     , d.diff_vty
     , d.diff_dists
  FROM ( SELECT t.start_date
              , SIGN( IFNULL( t.high     ,@high     ) - @high     ) AS diff_high
              , SIGN( IFNULL( t.low      ,@low      ) - @low      ) AS diff_low
              , SIGN( IFNULL( t.close    ,@close    ) - @close    ) AS diff_close
              , SIGN( IFNULL( t.vol      ,@vol      ) - @vol      ) AS diff_vol
              , SIGN( IFNULL( t.vol_avg  ,@vol_avg  ) - @vol_avg  ) AS diff_vol_avg
              , SIGN( IFNULL( t.range_   ,@range_   ) - @range_   ) AS diff_range_
              , SIGN( IFNULL( t.poc_     ,@poc_     ) - @poc_     ) AS diff_poc_
              , SIGN( IFNULL( t.va_h     ,@va_h     ) - @va_h     ) AS diff_va_h
              , SIGN( IFNULL( t.va_l     ,@va_l     ) - @va_l     ) AS diff_va_l
              , SIGN( IFNULL( t.va_range ,@va_range ) - @va_range ) AS diff_va_range
              , SIGN( IFNULL( t.tpot     ,@tpot     ) - @tpot     ) AS diff_tpot
              , SIGN( IFNULL( t.tpo_ab   ,@tpo_ab   ) - @tpo_ab   ) AS diff_tpo_ab
              , SIGN( IFNULL( t.tpo_bl   ,@tpo_bl   ) - @tpo_bl   ) AS diff_tpo_bl
              , SIGN( IFNULL( t.sf       ,@sf       ) - @sf       ) AS diff_sf
              , SIGN( IFNULL( t.tff      ,@tff      ) - @tff      ) AS diff_tff
              , SIGN( IFNULL( t.rf       ,@rf       ) - @rf       ) AS diff_rf
              , SIGN( IFNULL( t.vty      ,@vty      ) - @vty      ) AS diff_vty
              , SIGN( IFNULL( t.dists    ,@dists    ) - @dists    ) AS diff_dists
              , @high       := t.high     AS c1
              , @low        := t.low      AS c2
              , @close      := t.close    AS c3
              , @vol        := t.vol      AS c4 
              , @vol_avg    := t.vol_avg  AS c5
              , @range_     := t.range_   AS c6
              , @poc_       := t.poc_     AS c7
              , @va_h       := t.va_h     AS c8
              , @va_l       := t.va_l     AS c9
              , @va_range   := t.va_range AS c10
              , @tpot       := t.tpot     AS c11
              , @tpo_ab     := t.tpo_ab   AS c12
              , @tpo_bl     := t.tpo_bl   AS c13
              , @sf         := t.sf       AS c14
              , @tff        := t.tff      AS c15
              , @rf         := t.rf       AS c16
              , @vty        := t.vty      AS c17
              , @dists      := t.dists    AS c18
           FROM ( SELECT @high       := NULL
                       , @low        := NULL
                       , @close      := NULL
                       , @vol        := NULL
                       , @vol_avg    := NULL
                       , @range_     := NULL
                       , @poc_       := NULL
                       , @va_h       := NULL
                       , @va_l       := NULL
                       , @va_range   := NULL
                       , @tpot       := NULL
                       , @tpo_ab     := NULL
                       , @tpo_bl     := NULL
                       , @sf         := NULL
                       , @tff        := NULL
                       , @rf         := NULL
                       , @vty        := NULL
                       , @dists      := NULL
                ) i
          CROSS
           JOIN bop_ppy t
          ORDER BY t.start_time
       ) d
 ORDER BY d.start_time

如果要将这些NULL值替换为零,则可以使用IFNULL(expr,0)将表达式包装在外部查询中。

它处理列的NULL值表示“无变化”,与前一个值相同。 (如果该值未知,我们不知道它是更高还是更低。)

如果您不想要零,并且想要在发生这种情况时返回NULL,请删除IFNULL包装函数和第二个参数,并只保留对表列的引用。