MySQL 8-不赞成使用表达式中的用户变量(复杂计算)

时间:2019-02-23 18:01:18

标签: mysql sql deprecation-warning user-variables

//编辑//

下面是原始问题,但是一个问题确实可以简化我的问题...如何在不使用用户变量的情况下获得以下输出?!

SELECT ID, @cumu_return:=IF(id = 1, 1, @cumu_return + (@cumu_return * ret)) AS cumulative_return 
FROM (
    SELECT 1 AS ID, 1 AS num, 0.1 AS ret UNION ALL
    SELECT 2 AS ID, 1 AS num, 0.1 AS ret UNION ALL
    SELECT 3 AS ID, 1 AS num, 0.1 AS ret UNION ALL
    SELECT 4 AS ID, 1 AS num, 0.1 AS ret UNION ALL
    SELECT 5 AS ID, 1 AS num, 0.1 AS ret
) t

//结束编辑//

我有一张桌子,如下...

CREATE TABLE `daily_return` (
  `id` int(11) NOT NULL,
  `list_id` int(11) NOT NULL,
  `last_updated` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `daily_return` float NOT NULL,
  `last_return` float NOT NULL, KEY (`id`)
)

“每日收益”是list_id价格的百分比变化,每天计算一次,last_return是第一个/起始收益数字。

我需要使用以下逻辑来计算累积回报率指标:

'Previous Day Return' + ('Previous Day Return' * 'Daily Return')

因此,我有以下查询...

INSERT INTO cmc_cumulative_return (list_id, last_updated, cumulative_return)
SELECT list_id, last_updated, cumulative_return FROM (
    SELECT id, list_id, last_updated, daily_return, last_return,
        @cumu_return:=IF(id = 1, last_return, @cumu_return + (@cumu_return * daily_return)) AS cumulative_return 
    FROM daily_return c
) t WHERE id <> 1;

当我在过程中运行此命令时,它会发出警告:

  

不建议在表达式中设置用户变量,并且将   在将来的版本中删除。请分别设置变量   语句代替。

我在stackoverflow上看到了其他一些类似的问题,但是它们都是简单的增量计算,可以用ROW_NUMBER()OVER或SUM()OVER代替,但是我无法弄清楚如何在上面的查询中删除变量

最初,我使用的是3-4个变量,但现在我将其简化为一个,并请您帮忙删除最后一个。

编辑2

查询实际数据:(包括戈登的计算结果)

SELECT id, list_id, last_updated, daily_return, last_return,
    @cumu_return:=IF(id = 1, last_return, @cumu_return + (@cumu_return * daily_return)) AS cumulative_return,
    (
        EXP(SUM(LN(1 + daily_return)) OVER (ORDER BY id)) / (1 + daily_return)
    ) as cumulative_return2
FROM (
    SELECT 1 AS id, 2 AS list_id, '2019-02-20' AS last_updated, 0 AS daily_return, 1.15 AS last_return UNION ALL
    SELECT 2 AS id, 2 AS list_id, '2019-02-21' AS last_updated, 0.0145999858 AS daily_return, 1.15 AS last_return UNION ALL
    SELECT 3 AS id, 2 AS list_id, '2019-02-22' AS last_updated, -0.0503679203 AS daily_return, 1.15 AS last_return UNION ALL
    SELECT 4 AS id, 2 AS list_id, '2019-02-23' AS last_updated, 0.0111594238 AS daily_return, 1.15 AS last_return
) t

1 个答案:

答案 0 :(得分:1)

您可以使用自然对数和幂运算来进行累计产品计算。

INSERT INTO cmc_cumulative_return (list_id, last_updated, cumulative_return)
    SELECT list_id, last_updated, 
           (MAX(CASE WHEN id = 1 THEN last_return END) OVER () *
            EXP(SUM(LN(1 + daily_return)) OVER (ORDER BY id)
               ) / (1 + daily_return)
           ) as cumulative_return
    FROM daily_return c;

如果您确实要排除id = 1的地方,则需要附加级别的子查询。

Here是db <>小提琴。