SELECT
toDate(max(time)) AS date,
facility,
argMax(value, time) AS current_value,
argMin(value, time) AS previous_value,
toString(current_value) || '/' || toString(previous_value) AS values
FROM (
SELECT *
FROM (
/* emulate the original table */
SELECT toDateTime(test_set.1) as time, test_set.2 facility, test_set.3 value
FROM (
SELECT arrayJoin([
('2017-09-09 10:11:12', 10002, 10),
('2017-09-10 11:11:12', 10001, 12),
('2017-09-12 12:11:12', 10002, 15),
('2017-09-15 13:11:12', 10001, 17),
('2017-09-02 14:11:12', 10002, 5),
('2017-09-02 15:11:12', 10001, 7),
('2017-09-01 16:11:12', 10002, 7),
('2017-09-01 17:11:12', 10001, 9)]) test_set))
/*WHERE time BETWEEN .. AND ..*/
ORDER BY facility, time DESC
LIMIT 2 BY facility)
GROUP BY facility
ORDER BY date;
/* result
┌───────date─┬─facility─┬─current_value─┬─previous_value─┬─values─┐
│ 2017-09-12 │ 10002 │ 15 │ 10 │ 15/10 │
│ 2017-09-15 │ 10001 │ 17 │ 12 │ 17/12 │
└────────────┴──────────┴───────────────┴────────────────┴────────┘
*/
查询每行的前一个值(将使用neighbor-window 函数):
SELECT time, facility, value,
neighbor(facility, -1, -1) previous_facility,
(facility != previous_facility ? -1 : neighbor(value, -1, -1)) previous_value,
toString(value) || '/' || (previous_value = -1 ? 'none' : toString(previous_value)) AS values
FROM (
SELECT *
FROM (
/* emulate the original table */
SELECT toDateTime(test_set.1) as time, test_set.2 facility, test_set.3 value
FROM (
SELECT arrayJoin([
('2017-09-01 01:02:03', 10002, 3 ),
('2017-09-02 01:02:03', 10001, 4 ),
('2017-09-04 01:02:03', 10002, 1 ),
('2017-09-05 01:02:03', 10001, 2 ),
('2017-09-09 01:02:03', 10002, 10),
('2017-09-10 01:02:03', 10001, 12),
('2017-09-12 01:02:03', 10002, 15),
('2017-09-15 01:02:03', 10001, 17)]) test_set))
/*WHERE time BETWEEN .. AND ..*/
ORDER BY facility, time)
ORDER BY time;
/* result:
┌────────────────time─┬─facility─┬─value─┬─previous_facility─┬─previous_value─┬─values─┐
│ 2017-09-01 01:02:03 │ 10002 │ 3 │ 10001 │ -1 │ 3/none │
│ 2017-09-02 01:02:03 │ 10001 │ 4 │ -1 │ -1 │ 4/none │
│ 2017-09-04 01:02:03 │ 10002 │ 1 │ 10002 │ 3 │ 1/3 │
│ 2017-09-05 01:02:03 │ 10001 │ 2 │ 10001 │ 4 │ 2/4 │
│ 2017-09-09 01:02:03 │ 10002 │ 10 │ 10002 │ 1 │ 10/1 │
│ 2017-09-10 01:02:03 │ 10001 │ 12 │ 10001 │ 2 │ 12/2 │
│ 2017-09-12 01:02:03 │ 10002 │ 15 │ 10002 │ 10 │ 15/10 │
│ 2017-09-15 01:02:03 │ 10001 │ 17 │ 10001 │ 12 │ 17/12 │
└─────────────────────┴──────────┴───────┴───────────────────┴────────────────┴────────┘
*/
类似的查询但使用runningDifference:
SELECT time, facility, value,
neighbor(facility, -1, -1) previous_facility,
runningDifference(value) delta,
(facility != previous_facility ? -1 : value - delta) AS previous_value,
toString(value) || '/' || (previous_value = -1 ? 'none' : toString(previous_value)) AS values
FROM (
SELECT *
FROM (
/* emulate the original table */
SELECT toDateTime(test_set.1) as time, test_set.2 facility, test_set.3 value
FROM (
SELECT arrayJoin([
('2017-09-01 01:02:03', 10002, 3 ),
('2017-09-02 01:02:03', 10001, 4 ),
('2017-09-04 01:02:03', 10002, 1 ),
('2017-09-05 01:02:03', 10001, 2 ),
('2017-09-09 01:02:03', 10002, 10),
('2017-09-10 01:02:03', 10001, 12),
('2017-09-12 01:02:03', 10002, 15),
('2017-09-15 01:02:03', 10001, 17)]) test_set))
/*WHERE time BETWEEN .. AND ..*/
ORDER BY facility, time)
ORDER BY time;
/*
┌────────────────time─┬─facility─┬─value─┬─previous_facility─┬─delta─┬─previous_value─┬─values─┐
│ 2017-09-01 01:02:03 │ 10002 │ 3 │ 10001 │ -14 │ -1 │ 3/none │
│ 2017-09-02 01:02:03 │ 10001 │ 4 │ -1 │ 0 │ -1 │ 4/none │
│ 2017-09-04 01:02:03 │ 10002 │ 1 │ 10002 │ -2 │ 3 │ 1/3 │
│ 2017-09-05 01:02:03 │ 10001 │ 2 │ 10001 │ -2 │ 4 │ 2/4 │
│ 2017-09-09 01:02:03 │ 10002 │ 10 │ 10002 │ 9 │ 1 │ 10/1 │
│ 2017-09-10 01:02:03 │ 10001 │ 12 │ 10001 │ 10 │ 2 │ 12/2 │
│ 2017-09-12 01:02:03 │ 10002 │ 15 │ 10002 │ 5 │ 10 │ 15/10 │
│ 2017-09-15 01:02:03 │ 10001 │ 17 │ 10001 │ 5 │ 12 │ 17/12 │
└─────────────────────┴──────────┴───────┴───────────────────┴───────┴────────────────┴────────┘
*/
键 (time, facility) 不太适合上述计算。
如果它是主要用例并且它在所需的日期范围内工作得相当缓慢然后考虑将密钥更改为(设施,时间) 或使用Data Skipping Indexes。