Select 数据在从第一个错误值到最后一个错误值的范围内
Select data in range from first bad value to last bad value
有这样的table和数据:
create table sensor_values(
dt DateTime default now(),
value UInt32
)
engine MergeTree()
partition by toYYYYMM(dt)
order by tuple();
insert into sensor_values(value) values (1), (2), (11), (13), (4), (17), (5), (8);
数据:
value
-----
1
2
11
13
4
17
5
8
我想要 select 从第一个错误值 (11) 到最后一个错误值 (17) 范围内的数据。错误值超过 10。
select之后的期望范围:
value
-----
11
13
4
17
我的第一个想法是定义值是否坏,然后计算(某种方式)累计和:
value isBad cumSum
--------------------
1 0 0
2 0 0
11 1 1
13 1 2
4 0 2
17 1 3
5 0 3
8 0 3
然后我会 select 从 min(cumSum) 到 max(cumSum) - 1 但我错过了最后一个错误值。
如何获取 select 结果中包含的最后一个值?
您可以尝试使用 window 函数(参见:runningDifference, neighbor)或数组函数:
SELECT arrayJoin(slice) as result
FROM (
SELECT
groupArray(data) AS arr,
arrayFirstIndex(x -> (x > 10), arr) AS first_index,
(length(arr) - arrayFirstIndex(x -> (x > 10), arrayReverse(arr)) + 1) AS last_index,
arraySlice(arr, first_index, last_index - first_index + 1) AS slice
FROM
(
/* test dataset */
SELECT arrayJoin([1, 2, 11, 13, 4, 17, 5, 8]) AS data
)
)
/*
┌─result─┐
│ 11 │
│ 13 │
│ 4 │
│ 17 │
└────────┘
*/
有这样的table和数据:
create table sensor_values(
dt DateTime default now(),
value UInt32
)
engine MergeTree()
partition by toYYYYMM(dt)
order by tuple();
insert into sensor_values(value) values (1), (2), (11), (13), (4), (17), (5), (8);
数据:
value
-----
1
2
11
13
4
17
5
8
我想要 select 从第一个错误值 (11) 到最后一个错误值 (17) 范围内的数据。错误值超过 10。
select之后的期望范围:
value
-----
11
13
4
17
我的第一个想法是定义值是否坏,然后计算(某种方式)累计和:
value isBad cumSum
--------------------
1 0 0
2 0 0
11 1 1
13 1 2
4 0 2
17 1 3
5 0 3
8 0 3
然后我会 select 从 min(cumSum) 到 max(cumSum) - 1 但我错过了最后一个错误值。
如何获取 select 结果中包含的最后一个值?
您可以尝试使用 window 函数(参见:runningDifference, neighbor)或数组函数:
SELECT arrayJoin(slice) as result
FROM (
SELECT
groupArray(data) AS arr,
arrayFirstIndex(x -> (x > 10), arr) AS first_index,
(length(arr) - arrayFirstIndex(x -> (x > 10), arrayReverse(arr)) + 1) AS last_index,
arraySlice(arr, first_index, last_index - first_index + 1) AS slice
FROM
(
/* test dataset */
SELECT arrayJoin([1, 2, 11, 13, 4, 17, 5, 8]) AS data
)
)
/*
┌─result─┐
│ 11 │
│ 13 │
│ 4 │
│ 17 │
└────────┘
*/