Mysql查询出错-将值添加到前一个日期值

8zzbczxx  于 2023-04-10  发布在  Mysql
关注(0)|答案(1)|浏览(134)

好日子-我没有地方开始这个查询!!
我有一行-列是日期,产品,值
价值观
| nr|伊普达特|产物|market_value_1|值计算|价值|
| --------------|--------------|--------------|--------------|--------------|--------------|
| 1|2021-01-01 2021- 01-01|ASISA|0.9990975600702915638|“0.90975600702915638”/“100”-1|0.9909024399297084|
| 二|2021-01-02 2021-01-02|ASISA|0.9990972000702915638|“0.9909024399297084”/“0.9990972000702915638”|0.9917978349453821|
| 三|2021-01-03 2021-01-03|ASISA|0.9890972000702915638|“0.9890972000702915638”|0.9972770308827713|
我需要从2021-01-01开始,执行Market_value_1/100 - 1,然后执行下一日期市场值/上一日期值,然后执行下一日期市场值/上一日期值,然后执行下一日期市场值/上一日期值
这是我正在尝试的代码

SELECT product,ipdate,
       market_value_1 mv1,
       row_num,
       @running,
       (@running := market_value_1/(SELECT IF(row_num = 1, 100, @running)))  AS running,
       ROUND(@running,8)
FROM (SELECT id,
             ipdate,
             product,
             market_value_1,
             (@row_num := @row_num + 1) AS row_num
      FROM report_combined
     GROUP BY product,ipdate
      ORDER BY product,ipdate) AS a"

但是我的行不会在每次产品更改时重置为1

7qhs6swi

7qhs6swi1#

您当前的查询是不确定的,因为您有GROUP BY product, ipdate,但idmarket_value_1列不包含在聚合函数中。在此基础上,我假设分组没有任何用途并将其省略。我也使用了您评论中描述的计算,而不是原始问题,但是当你弄清楚计算应该是什么的时候,你可以根据需要修改它。
要为每个产品重置当前查询,您可以与上一个产品进行比较,而不是使用行号:

SELECT
    product,
    ipdate,
    market_value_1,
    (@running := market_value_1/(IF(product <> @prev_product, 100, @running)) - 1) AS running,
    ROUND(@running, 8),
    @prev_product := product
FROM report_combined
JOIN (SELECT @prev_product := '', @running := 0) vars
ORDER BY product, ipdate;

注意:这是MySQL 8在使用此方法时生成的警告:
不建议在表达式中设置用户变量,并且将在未来版本中删除。请考虑以下替代方案:'SET variable=expression,...'或'SELECT expression(s)INTO variables(s)'。
实现这一点的另一种方法是使用递归CTE:

WITH RECURSIVE cte (id, ipdate, product, market_value_1, calc) AS (
    SELECT
        id, ipdate, product, market_value_1,
        market_value_1/100 - 1
    FROM report_combined
    WHERE ipdate = '2021-01-01'

    UNION ALL

    SELECT
        rc.id, rc.ipdate, rc.product, rc.market_value_1,
        rc.market_value_1/cte.calc - 1
    FROM cte
    JOIN report_combined rc
        ON cte.product = rc.product
        AND cte.ipdate + INTERVAL 1 DAY = rc.ipdate
        AND rc.ipdate <= '2021-12-31'
)
SELECT * FROM cte;

来自手册:
第一个SELECT生成CTE的初始行,并且不引用CTE名称。第二个SELECT生成其他行,并通过引用其FROM子句中的CTE名称进行递归。当此部分不生成新行时,递归结束。因此,递归CTE由非递归SELECT部分和递归SELECT部分组成。
此方法假定日期范围没有间隙。如果周末或银行假日有间隙,则可以使用另一个CTE首先创建连续序列。

相关问题