我有一个这种格式的表格
时间戳 | sys_id | 产品名称 | 值名称 | 价值 |
---|---|---|---|---|
2024-01-03 00:35:00+05:30 | 1 | a | 字节 | 10 |
2024-01-03 00:35:00+05:30 | 2 | a | 字节 | 20 |
2024-01-03 00:35:00+05:30 | 3 | a | 字节 | 30 |
2024-01-03 00:40:00+05:30 | 1 | a | 字节 | 20 |
2024-01-03 00:40:00+05:30 | 2 | a | 字节 | 20 |
2024-01-03 00:40:00+05:30 | 3 | a | 字节 | 40 |
对于给定的一组time_stamp、sys_id、Product_name、valuename,我想找到该组的当前条目和上一个条目之间的差异 如果差值等于 0,那么我希望该组的另一列 Break_status 被标记为 1,否则为 0 因此,当我在 where 子句中给出 sys_id 时,我使用 lag() 函数,它工作正常,下面是 sql 查询和表输出
SELECT
TO_CHAR(time_stamp) as Time,
TO_CHAR(sys_id) as System_ID,
product_name,
valuename,
TO_CHAR(value),
(value - LAG(value, 1) OVER (ORDER BY time_stamp)) as diff,
CASE WHEN value = 0 or diff = 0 or diff is null THEN 0 ELSE 1 END AS breach_status
FROM table
WHERE valuename='bytes' and system_id = '2' and
time_stamp BETWEEN '2024-01-03 00:35:00' AND '2024-01-03 00:40:00'
ORDER BY time_stamp
时间戳 | sys_id | 产品名称 | 值名称 | 价值 | 差异 | 违规状态 |
---|---|---|---|---|---|---|
2024-01-03 00:35:00+05:30 | 1 | a | 字节 | 10 | 0 | |
2024-01-03 00:35:00+05:30 | 2 | a | 字节 | 20 | 0 | |
2024-01-03 00:35:00+05:30 | 3 | a | 字节 | 30 | 0 | |
2024-01-03 00:40:00+05:30 | 1 | a | 字节 | 20 | 10 | 0 |
2024-01-03 00:40:00+05:30 | 2 | a | 字节 | 20 | 0 | 1 |
2024-01-03 00:40:00+05:30 | 3 | a | 字节 | 40 | 10 | 0 |
此处,对于时间戳 = '2024-01-03 00:40:00+05:30'、sys_id = 2、product_name = 'a' 且 valuename = 'bytes',值差异为 0,因此,breach_status 为 1
但是这里我想使用分组依据,因为时间戳,sys_id,product_name,valuename记录有多种不同的组合。
因此我想在上面的查询中使用 group by
SELECT
TO_CHAR(time_stamp) as Time,
TO_CHAR(system_id) as System_ID,
customer_name,
valuename,
TO_CHAR(max(value)) as val,
(max(value) - LAG(max(value), 1) OVER (ORDER BY time_stamp)) as diff,
CASE WHEN value = 0 or diff = 0 or diff is null THEN 0 ELSE 1 END AS breach_status
FROM table
WHERE
time_stamp BETWEEN '2024-01-03 00:35:00' AND '2024-01-03 00:40:00'
group by
time_stamp,
system_id,
customer_name,
valuename
ORDER BY time_stamp, diff, breach_status
但这里不是使用检查其集合之前条目之间的差异,而是检查与其上面条目的差异
时间戳 | sys_id | 产品名称 | 值名称 | 价值 | 差异 | 违规状态 |
---|---|---|---|---|---|---|
2024-01-03 00:35:00+05:30 | 1 | a | 字节 | 10 | 0 | |
2024-01-03 00:35:00+05:30 | 2 | a | 字节 | 20 | 10 | 0 |
2024-01-03 00:35:00+05:30 | 3 | a | 字节 | 30 | 10 | 0 |
2024-01-03 00:40:00+05:30 | 1 | a | 字节 | 20 | -10 | 0 |
2024-01-03 00:40:00+05:30 | 2 | a | 字节 | 20 | 0 | 1 |
2024-01-03 00:40:00+05:30 | 3 | a | 字节 | 40 | -20 | 0 |
我将如何使用此查询 最后,我将在 grafana 仪表板中使用此查询来根据违规值发出警报,因此在 select 语句中我希望所有内容都在 CHAR 中,因此我使用 to_char() 将其转换 但是如果我将 diff 列转换为 char 那么我们就无法在违规条件下比较它,因为它是字符串而不是数字。
你可以参考这个 sql 两行之间的差异与 group by
这是您需要的查询
SELECT
TO_CHAR(time_stamp) as Time,
TO_CHAR(system_id) as System_ID,
customer_name,
valuename,
TO_CHAR(max(value)) as val,
(max(value) - LAG(max(value), 1) OVER (partition by system_id, customer_name, valuename ORDER BY time_stamp)) as diff,
CASE WHEN value = 0 or diff = 0 or diff is null THEN 0 ELSE 1 END AS breach_status
FROM table
WHERE
time_stamp BETWEEN '2024-01-03 00:35:00' AND '2024-01-03 00:40:00'
group by
time_stamp,
system_id,
customer_name,
valuename
ORDER BY time_stamp```