【问题标题】:Get percentage based on value in previous row根据上一行中的值获取百分比
【发布时间】:2019-11-13 08:53:10
【问题描述】:

对于给定的数据:

+---+--------+------+
|CID| number | rum  |
+---+--------+------+
| 1 | 1.0000 | NULL |
| 3 | 2.0000 | NULL |
| 5 | 2.0000 | NULL |
| 6 | 4.0000 | NULL |
+---+--------+------+

我想用当前和以前数字的百分比变化来计算朗姆酒。

rum = (currNumber - prevNumber) / prevNumber * 100

预期结果:

+---+--------+------+
|CID| number | rum  |
+---+--------+------+
| 1 | 1.0000 | NULL |
| 3 | 2.0000 |100.0 |
| 5 | 2.0000 |  0.0 |
| 6 | 4.0000 |100.0 |
+---+--------+------+

LAG 函数在 MySQL 中不起作用。

【问题讨论】:

    标签: mysql sql window-functions


    【解决方案1】:

    假设行是根据 CID 排序的,您可以使用相关子查询找到上一行:

    SELECT CID, number, (
        SELECT (c.number - p.number) / p.number * 100
        FROM t AS p
        WHERE p.CID < c.CID
        ORDER BY p.CID DESC
        LIMIT 1
    ) AS rum
    FROM t AS c
    

    SQL Fiddle

    【讨论】:

      【解决方案2】:

      您可以使用变量模拟lag()

      set @num = null;
      
      select 
          cid,
          number,
          (number- lag_number)/lag_number * 100 rum
      from (
          select 
              cid, 
              @num lag_number, 
              @num := number number 
          from mytable 
          order by cid
      ) t
      order by cid
      

      Demo on DB Fiddle

      西德 |号码 |朗姆酒 --: | -----: | ---: 1 | 1.0000 | 3 | 2.0000 | 100 5 | 2.0000 | 0 6 | 4.0000 | 100

      【讨论】:

      • 为此使用变量是个坏主意。
      • 子查询中有一个order by。这是无稽之谈,但 MySQL 允许您这样做,但它可能会也可能不会尊重内部顺序。没有保证。
      • @SalmanA:据我所知,子查询中的 order by 子句保证了变量将被正确分配前一个值。但我不得不同意,无论如何,您的解决方案在这里更聪明,因此 +1。
      • @gmb mysqlserverteam.com/…... 搜索“与国家结伴”。
      猜你喜欢
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      • 2018-12-24
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多