我有一个来自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。
我曾尝试首先对表进行自我连接,然后将虚拟变量分配给连续行之间的差异,但到目前为止这还没有奏效。我不知道如何让这个工作了。请有人帮忙。
答案 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包装函数和第二个参数,并只保留对表列的引用。