如何使用 LAG 函数和 IF-THEN-ELSE 在 SQLite3 中创建永久(存储)生成(计算/计算)列?

问题描述 投票:0回答:1

我有以下数据(此处的子集):

datetime,sys_id,cputil,memfree,sessnum
2019/05/03 08:06:14,100,0.57,0.51,47
2019/05/03 08:11:14,100,0.47,0.62,43
2019/05/03 08:16:14,100,0.56,0.57,62
2019/05/03 08:21:14,100,0.57,0.56,50
2019/05/03 08:26:14,100,0.35,0.46,43
2019/05/03 08:31:14,100,0.41,0.58,48
2019/05/03 08:36:14,100,0.57,0.35,58
2019/05/03 08:41:14,100,0.41,0.4,58
2019/05/03 08:46:14,100,0.53,0.35,62
2019/05/03 08:51:14,100,0.51,0.6,45
2019/05/03 08:56:14,100,0.32,0.37,47
2019/05/03 09:01:14,100,0.62,0.59,60
2019/05/03 09:06:14,100,0.66,0.72,57
2019/05/03 09:11:14,100,0.54,0.54,44
2019/05/03 09:16:14,100,0.29,0.4,47
2019/05/03 09:21:14,100,0.43,0.68,66
2019/05/03 09:26:14,100,0.49,0.66,65
2019/05/03 09:31:14,100,0.64,0.55,66
2019/05/03 09:36:14,100,0.42,0.6,42
2019/05/03 09:41:14,100,0.55,0.59,63

我需要创建一个永久计算列来跟踪

cpu_util
memfree
列的差异。也就是说,对于每一行,我需要知道它与同一列中的前一行相比发生的变化量。

所以表格应该是这样的:

datetime,sys_id,cputil,memfree,sessnum,util_diff,mem_diff
2019/05/03 08:06:14,100,0.57,0.51,47,[NULL],[NULL]
2019/05/03 08:11:14,100,0.47,0.62,43,-0.1,0.11
2019/05/03 08:16:14,100,0.56,0.57,62,0.0900000000000001,-0.05
2019/05/03 08:21:14,100,0.57,0.56,50,0.0099999999999999,-0.0099999999999999
2019/05/03 08:26:14,100,0.35,0.46,43,-0.22,-0.1
2019/05/03 08:31:14,100,0.41,0.58,48,0.06,0.12
2019/05/03 08:36:14,100,0.57,0.35,58,0.16,-0.23
2019/05/03 08:41:14,100,0.41,0.4,58,-0.16,0.05
2019/05/03 08:46:14,100,0.53,0.35,62,0.12,-0.05
2019/05/03 08:51:14,100,0.51,0.6,45,-0.02,0.25
2019/05/03 08:56:14,100,0.32,0.37,47,-0.19,-0.23
2019/05/03 09:01:14,100,0.62,0.59,60,0.3,0.22
2019/05/03 09:06:14,100,0.66,0.72,57,0.04,0.13
2019/05/03 09:11:14,100,0.54,0.54,44,-0.12,-0.18
2019/05/03 09:16:14,100,0.29,0.4,47,-0.25,-0.14
2019/05/03 09:21:14,100,0.43,0.68,66,0.14,0.28
2019/05/03 09:26:14,100,0.49,0.66,65,0.06,-0.02
2019/05/03 09:31:14,100,0.64,0.55,66,0.15,-0.11
2019/05/03 09:36:14,100,0.42,0.6,42,-0.22,0.0499999999999999
2019/05/03 09:41:14,100,0.55,0.59,63,0.13,-0.01

我找到了有关使用

LAG
函数的各种教程,但是当尝试在
LAG
列上下文而不是
GENERATED
语句上下文中使用
SELECT
时,我无法让它工作。

每次添加新行时都需要自动计算和更新。

也在

PostgreSQL
中尝试此操作,我有以下代码用于创建原始表,没有必要的差异列:

CREATE TABLE myTable (
    datetime TEXT,
    sys_id INT,
    cputil REAL,
    memfree REAL,
    sessnum INT
)

这很好。

现在,我需要表具有自动计算的额外列(

GENERATED
),但是当我尝试以下操作时,它失败了:

CREATE TABLE myTable (
    datetime TEXT,
    sys_id INT,
    cputil REAL,
    memfree REAL,
    sessnum INT,
    util_diff REAL GENERATED ALWAYS AS (cputil - LAG(cputil)) OVER (ORDER BY datetime) STORED,
    mem_diff REAL GENERATED ALWAYS AS (memfree - LAG(memfree)) OVER (ORDER BY datetime) STORED
)

注意:出于

datetime
(行排序)的目的,假设
YYYY/MM/DD
格式为
ORDER BY

我知道我可能需要创建额外的“中间”列来保存

LAG
输出,如下所示:

datetime,sys_id,cputil,memfree,sessnum,util_lag,mem_lag,util_diff,mem_diff
2019/05/03 08:06:14,100,0.57,0.51,47,[NULL],[NULL],[NULL],[NULL]
2019/05/03 08:11:14,100,0.47,0.62,43,0.57,0.51,-0.1,0.11
2019/05/03 08:16:14,100,0.56,0.57,62,0.47,0.62,0.0900000000000001,-0.05
2019/05/03 08:21:14,100,0.57,0.56,50,0.56,0.57,0.0099999999999999,-0.0099999999999999
2019/05/03 08:26:14,100,0.35,0.46,43,0.57,0.56,-0.22,-0.1
2019/05/03 08:31:14,100,0.41,0.58,48,0.35,0.46,0.06,0.12
2019/05/03 08:36:14,100,0.57,0.35,58,0.41,0.58,0.16,-0.23
2019/05/03 08:41:14,100,0.41,0.4,58,0.57,0.35,-0.16,0.05
2019/05/03 08:46:14,100,0.53,0.35,62,0.41,0.4,0.12,-0.05
2019/05/03 08:51:14,100,0.51,0.6,45,0.53,0.35,-0.02,0.25
2019/05/03 08:56:14,100,0.32,0.37,47,0.51,0.6,-0.19,-0.23
2019/05/03 09:01:14,100,0.62,0.59,60,0.32,0.37,0.3,0.22
2019/05/03 09:06:14,100,0.66,0.72,57,0.62,0.59,0.04,0.13
2019/05/03 09:11:14,100,0.54,0.54,44,0.66,0.72,-0.12,-0.18
2019/05/03 09:16:14,100,0.29,0.4,47,0.54,0.54,-0.25,-0.14
2019/05/03 09:21:14,100,0.43,0.68,66,0.29,0.4,0.14,0.28
2019/05/03 09:26:14,100,0.49,0.66,65,0.43,0.68,0.06,-0.02
2019/05/03 09:31:14,100,0.64,0.55,66,0.49,0.66,0.15,-0.11
2019/05/03 09:36:14,100,0.42,0.6,42,0.64,0.55,-0.22,0.0499999999999999
2019/05/03 09:41:14,100,0.55,0.59,63,0.42,0.6,0.13,-0.01

在这种情况下,SQL 应该如下所示:

CREATE TABLE myTable (
    datetime TEXT,
    sys_id INT,
    cputil REAL,
    memfree REAL,
    sessnum INT,
    util_lag REAL GENERATED ALWAYS AS LAG(cputil) OVER (ORDER BY datetime) STORED,
    mem_lag REAL GENERATED ALWAYS AS LAG(memfree) OVER (ORDER BY datetime) STORED,
    util_diff REAL GENERATED ALWAYS AS (cputil - util_lag) STORED,
    mem_diff REAL GENERATED ALWAYS AS (memfree - mem_lag) STORED
)

我需要添加到表中的最后一个计算列是一个文本字符串,指示更改(与上一行的差异)是“向上”还是“向下”,因此最终表应如下所示:

datetime,sys_id,cputil,memfree,sessnum,util_lag,mem_lag,util_diff,mem_diff,change
2019/05/03 08:06:14,100,0.57,0.51,47,[NULL],[NULL],[NULL],[NULL],[NULL]
2019/05/03 08:11:14,100,0.47,0.62,43,0.57,0.51,-0.1,0.11,Down
2019/05/03 08:16:14,100,0.56,0.57,62,0.47,0.62,0.0900000000000001,-0.05,Up
2019/05/03 08:21:14,100,0.57,0.56,50,0.56,0.57,0.0099999999999999,-0.0099999999999999,Up
2019/05/03 08:26:14,100,0.35,0.46,43,0.57,0.56,-0.22,-0.1,Down
2019/05/03 08:31:14,100,0.41,0.58,48,0.35,0.46,0.06,0.12,Up
2019/05/03 08:36:14,100,0.57,0.35,58,0.41,0.58,0.16,-0.23,Up
2019/05/03 08:41:14,100,0.41,0.4,58,0.57,0.35,-0.16,0.05,Down
2019/05/03 08:46:14,100,0.53,0.35,62,0.41,0.4,0.12,-0.05,Up
2019/05/03 08:51:14,100,0.51,0.6,45,0.53,0.35,-0.02,0.25,Down
2019/05/03 08:56:14,100,0.32,0.37,47,0.51,0.6,-0.19,-0.23,Down
2019/05/03 09:01:14,100,0.62,0.59,60,0.32,0.37,0.3,0.22,Up
2019/05/03 09:06:14,100,0.66,0.72,57,0.62,0.59,0.04,0.13,Up
2019/05/03 09:11:14,100,0.54,0.54,44,0.66,0.72,-0.12,-0.18,Down
2019/05/03 09:16:14,100,0.29,0.4,47,0.54,0.54,-0.25,-0.14,Down
2019/05/03 09:21:14,100,0.43,0.68,66,0.29,0.4,0.14,0.28,Up
2019/05/03 09:26:14,100,0.49,0.66,65,0.43,0.68,0.06,-0.02,Up
2019/05/03 09:31:14,100,0.64,0.55,66,0.49,0.66,0.15,-0.11,Up
2019/05/03 09:36:14,100,0.42,0.6,42,0.64,0.55,-0.22,0.0499999999999999,Down
2019/05/03 09:41:14,100,0.55,0.59,63,0.42,0.6,0.13,-0.01,Up

所以我正在尝试以下代码:

CREATE TABLE myTable (
    datetime TEXT,
    sys_id INT,
    cputil REAL,
    memfree REAL,
    sessnum INT,
    util_lag REAL GENERATED ALWAYS AS LAG(cputil) OVER (ORDER BY datetime) STORED,
    mem_lag REAL GENERATED ALWAYS AS LAG(memfree) OVER (ORDER BY datetime) STORED,
    util_diff REAL GENERATED ALWAYS AS (cputil - util_lag) STORED,
    mem_diff REAL GENERATED ALWAYS AS (memfree - mem_lag) STORED,
    change TEXT GENERATED ALWAYS AS CAST (
        CASE
            WHEN util_diff > 0 THEN 'Down'
            WHEN util_diff < 0 THEN 'Up'
    ) END AS STORED
)

但是,这又失败并出现错误。

最后,我需要知道在

SQLite3
以及
PostgreSQL
中执行此操作的正确语法。

sql postgresql sqlite calculated-columns lag
1个回答
0
投票

这是不可能的,您不能为此使用生成的列。来自手册

The generation expression can only use immutable functions and cannot use subqueries or reference anything other than the current row in any way.

您可以为此创建一个触发器+触发器函数。

© www.soinside.com 2019 - 2024. All rights reserved.