PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Sumuj do osiągnięcia wartości progowej, a następnie zresetuj licznik

Użyj agregatu zdefiniowanego przez użytkownika

Test na żywo:http://sqlfiddle.com/#!17/16716/2

SELECT *, sum_with_reset(distance, 10) over (order by date asc) as running_distance 
FROM tbl;

Definicja zagregowanej sumy_z_resetem zdefiniowana przez użytkownika:

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
);

Dane

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)
;

Wyjście:

| 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 |

Jednowierszowy:

create or replace function sum_reset_accum(
    _accumulated numeric, _current numeric, _threshold numeric
)
returns numeric as
$$
    select _current + _accumulated * (_accumulated < _threshold)::int
$$ language 'sql';

Wartość logiczna Postgresa może rzutować true na 1, false na 0 za pomocą operatora rzutowania ::int .

Możesz użyć plpgsql też język:

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';

Zauważ, że nie możesz utworzyć funkcji plpgsql na sqlfiddle.com, więc nie możesz przetestować tego kodu plpgsql na sqlfiddle.com. Możesz jednak na swoim komputerze.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wykonać kopię zapasową bazy danych Postgres w Kubernetes w Google Cloud?

  2. Połączenie z postgresem z maszynopisu zawiesza się

  3. Jak pracować z ułamkami dziesiętnymi o wysokiej precyzji w PHP?

  4. Sortowanie rekordów z PostgreSQL z wieloma miejscami dziesiętnymi (.)

  5. Czy możliwe jest łatanie ładowanych instrukcji SQL z pliku przy użyciu clojure.java.jdbc?