文档中心MogDBMogDB StackUqbar

文档:v2.0

支持的版本:

其他版本:

derivative()

功能描述

计算相邻的两行值的变化率,可通过ORDER BY进行排序。

相邻两行的时间为t1、t2,其差值单位为us,derivative对应的value列的值为v1、v2,其单位为v,derivative的每个时间单位为unit,每个单位中的时间长度为k微秒,变化率计算公式如下,其结果单位为[1/unit]

img

例如,原始数据如下:

time 01:00:00 01:10:00 01:30:00 02:00:00 02:10:00
value 31 32 33 34 36

使用derivative(value,time,’10min’),计算结果如下,将会去除第一行,并计算之后几行的变化率:

time 01:10:00 01:30:00 02:00:00 02:10:00
derivative 1.0 0.5 0.33333... 2.0

语法格式

derivative(value, time, unit)

参数说明

参数名 类型 属性 释义
value 数值型 必选 需要计算变化率的列或者列表达式。
支持列的数据类型范围:TINYINT、SMALLINT、INTEGER、BIGINT、FLOAT4、FLOAT8
如果使用NUMERIC、DECIMAL、NUMBER、BINARY_DOUBLE、INTEGER[(p[,s])]、DEC等其他数值类型,将会产生隐式类型转换,从该类型转换到FLOAT8,value的大小不应该超过FLOAT8的上限。
表达式类型:COUNT()、MEDIAN()、SUM()、FIRST()、LAST()、MIN()、MAX()、AVG()、LOCF()、INTERPOLATE() 。
time TIMESTAMP或TIMESTAMPTZ 必选 进行计算变化率的时间列/或时间表达式,当使用GAPFILL作为时间列时,将当前参数设置为NULL,并需要将GAPFILL放到TargetList中去。
支持的表达式类型:TIME_BUCKET()
unit INTEVAL 可选 计算变化率的单位,默认1s,支持从字符串隐式转换为INTERVAL,比如’1h’会被转换为’1h’::INTERVAL。unit的值不能为负。可选范围:s、min、hour、day、week。
假设第一行时间为17:10:00.20,值为10
假设第二行时间为17:15:00.30,值为20
时间相差结果保留到Interval,其基础单位为1us,那么time_unit=1000000L,以下用[]来表示单位。
变化率应为(20-10)/((17:15:00.30-17:10:00.20)[us]/1000000L[us/unit]) = (20-10)*1000000L/((17:15:00.30-17:10:00.20) [unit]),假设值的单位为T,最后结果的单位应该是[T/unit],表示以每个单位为基准的变化率。

约束

  1. 如果相邻的两行数据,时间差(绝对值)小于unit单位,则报错。

  2. 在derivative中不支持嵌套使用derivative或difference,无论是在derivative的value列或是在time列,还是在unit列。

  3. 使用ORDER BY确定对原始数据如何排序,derivative计算的结果将会在原始数据排序后进行计算。

  4. 如果相邻两行的time列相同,那么将会忽略第二行。

  5. 当derivative引用的某一行的value列或time列为空时,将忽略该行,不计算该行的变化率,而是计算上一个value列和time列均不为空的行到下一个value列和time列均不为空的行之间的变化率。

  6. 在TargetList中可能使用一个或多个derivative函数,也可能在使用derivative函数的同时使用一个或多个difference函数进行计算,当前规则适用于以上提及的两种情况,因此derivative函数和difference函数统称为D函数。当结果中的一行中有多个D函数计算结果时,如果所有D函数计算的结果均为空,则跳过这一行。如果任意一个D函数不为空,则保留当前行。但只有不为空的D函数会被输出到结果,其他列均为NULL。

  7. 兼容time_bucket_gapfill的特殊用法,如果要在时间列使用gapfill,那么需要将time参数设置为NULL,并且在TargetList使用time_bucket_gapfill(需要同时满足这两个条件才生效),例如:

    SELECT time_bucket_gapfill('10 mins', time) AS ten_mins, derivative(avg(value),NULL,NULL)
    FROM test_gapfill
    where time > '2030-01-01 01:00:00' and time < '2030-01-01 02:20:00'
    GROUP BY ten_mins;

    除此之外支持locf/interpolate,示例如下:

    SELECT time_bucket_gapfill('10 mins', time) AS ten_mins, derivative(locf(avg(value)),NULL,NULL)
    FROM test_gapfill
    where time > '2030-01-01 01:00:00' and time < '2030-01-01 02:20:00'
    GROUP BY ten_mins;
  8. 如果不在TargetList中显式使用derivative,例如在group by、distinct、order by等子句中使用,那么derivative的作用是将value列转换为Numeric,而不会进行任何计算,例如:

    select avg(value)
    from test_gapfill
    group by derivative(value,time,NULL);
  9. 在group by中使用time_bucket并在derivative中使用time_bucket作为time列时,需要保持bucket_width格式一致(包括增加减少空格),例如以下语句可以正常运行:

    select time_bucket('2 hour', time) as bucket,
    derivative(avg(temperature), time_bucket('2 hour', time), '2hour') 
    from weather group by bucket order by bucket;

    但当使用不同格式时,将无法运行:

    select time_bucket('2 hour', time) as bucket,
    derivative(avg(temperature), time_bucket('120min', time), '2hour') 
    from weather group by bucket order by bucket;
  10. 支持普通表。

  11. 返回值为Numeric。

  12. 相邻两列时间相同时,将会忽略当前行与上一行的计算结果。

示例

-- 数据样例
Uqbar=# select * from weather;
          time          | city  | temperature 
------------------------+-------+-------------
 2023-02-14 09:00:00+08 | jinan |          10
 2023-02-14 10:00:00+08 | jinan |          11
 2023-02-14 11:00:00+08 | jinan |        12.5
 2023-02-14 12:00:00+08 | jinan |          13
 2023-02-14 13:00:00+08 | jinan |          14
(5 rows)

-- 查询每小时温度变化率
Uqbar=# select time,derivative(temperature, time,'1h') from weather order by time;
          time          |       derivative       
------------------------+------------------------
 2023-02-14 10:00:00+08 |     1
 2023-02-14 11:00:00+08 |       1.5
 2023-02-14 12:00:00+08 |      .5
 2023-02-14 13:00:00+08 |     1
(4 rows)
 
-- 查询每半小时温度变化率
Uqbar=# select time,derivative(temperature, time, '30min') from weather order by time;
          time          |      derivative       
------------------------+-----------------------
 2023-02-14 10:00:00+08 |     .5
 2023-02-14 11:00:00+08 |     .75
 2023-02-14 12:00:00+08 |     .25
 2023-02-14 13:00:00+08 |     .5
(4 rows)
 
-- 查询每两小时温度变化率
Uqbar=# select time_bucket('2 hour', time) as bucket,derivative(avg(temperature), time_bucket('2 hour', time), '2hour') from weather group by bucket order by bucket;
         bucket         |     derivative     
------------------------+--------------------
 2023-02-14 10:00:00+08 |   1.75
 2023-02-14 12:00:00+08 |   1.75
(2 rows)

-- 特殊用法,使用time_bucket_gapfill查询每30分钟温度变化率
Uqbar=# SELECT time_bucket_gapfill('30 mins', time) AS bucket, derivative(locf(avg(temperature)),NULL,'30min')
FROM weather where time >= '2023-02-14 09:00:00+08' and time <= '2023-02-14 13:00:00+08' GROUP BY bucket;
         bucket         |           derivative           
------------------------+--------------------------------
 2023-02-14 09:30:00+08 |       0
 2023-02-14 10:00:00+08 |             1
 2023-02-14 10:30:00+08 |       0
 2023-02-14 11:00:00+08 |               1.5
 2023-02-14 11:30:00+08 |       0
 2023-02-14 12:00:00+08 |            .5
 2023-02-14 12:30:00+08 |       0
 2023-02-14 13:00:00+08 |             1
(8 rows)

-- 补充数据样例
Uqbar=# select * from weather;
          time          | city  | temperature | pressure
-------------------------------------+---------+--------------------+------------------
 2023-02-14 09:00:00+08 | jinan |          10   |   23
 2023-02-14 10:00:00+08 | jinan |           |   24
 2023-02-14 11:00:00+08 | jinan |        12.5    |    
 2023-02-14 12:00:00+08 | jinan |           |    
 2023-02-14 13:00:00+08 | jinan |          14  |   25
(5 rows)

-- 约束5使用示例
Uqbar=# select time, derivative(temperature , time,'1h') ,derivative(pressure, time,'1h') from weather order by time;
          time          | difference   | difference
------------------------+------------+------------
 2023-02-14 10:00:00+08 |            |  1
 2023-02-14 11:00:00+08 |        1.25  |  
 2023-02-14 13:00:00+08 |        0.75  |  0.333333
(3 rows)
Copyright © 2011-2024 www.enmotech.com All rights reserved.