Sử dụng tổng hợp do người dùng xác định
Kiểm tra trực tiếp: http://sqlfiddle.com/#!17/16716/2
SELECT *, sum_with_reset(distance, 10) over (order by date asc) as running_distance
FROM tbl;
Định nghĩa sum_with_reset tổng hợp do người dùng xác định:
create or replace function sum_reset_accum(
_accumulated numeric, _current numeric, _threshold numeric
)
returns numeric as
$$
select case when _accumulated >= _threshold then
_current
else
_current + _accumulated
end
$$ language sql;
create aggregate sum_with_reset(numeric, numeric)
(
sfunc = sum_reset_accum,
stype = numeric,
initcond = 0
);
Dữ liệu
CREATE TABLE tbl
("user_id" int, "date" timestamp, "distance" int)
;
INSERT INTO tbl
("user_id", "date", "distance")
VALUES
(1, '2019-04-09 00:00:00', 2),
(1, '2019-04-09 00:00:30', 5),
(1, '2019-04-09 00:01:00', 3),
(1, '2019-04-09 00:01:45', 7),
(1, '2019-04-09 00:02:30', 6),
(1, '2019-04-09 00:03:00', 1)
;
Đầu ra:
| user_id | date | distance | running_distance |
|---------|----------------------|----------|------------------|
| 1 | 2019-04-09T00:00:00Z | 2 | 2 |
| 1 | 2019-04-09T00:00:30Z | 5 | 7 |
| 1 | 2019-04-09T00:01:00Z | 3 | 10 |
| 1 | 2019-04-09T00:01:45Z | 7 | 7 |
| 1 | 2019-04-09T00:02:30Z | 6 | 13 |
| 1 | 2019-04-09T00:03:00Z | 1 | 1 |
Một lớp lót:
create or replace function sum_reset_accum(
_accumulated numeric, _current numeric, _threshold numeric
)
returns numeric as
$$
select _current + _accumulated * (_accumulated < _threshold)::int
$$ language 'sql';
Boolean Postgres có thể ép kiểu true thành 1, false thành 0 bằng cách sử dụng toán tử ép kiểu ::int
.
Bạn có thể sử dụng plpgsql
ngôn ngữ nữa:
create or replace function sum_reset_accum(
_accumulated numeric, _current numeric, _threshold numeric
)
returns numeric as
$$begin
return _current + _accumulated * (_accumulated < _threshold)::int;
end$$ language 'plpgsql';
Lưu ý rằng bạn không thể tạo hàm plpgsql trên sqlfiddle.com, vì vậy bạn không thể kiểm tra mã plpgsql đó trên sqlfiddle.com. Tuy nhiên, bạn có thể trên máy của mình.