sql >> Databáze >  >> RDS >> PostgreSQL

Sčítat, dokud není dosaženo prahové hodnoty, a poté vynulovat počítadlo

Použijte uživatelsky definovaný agregát

Živý test:http://sqlfiddle.com/#!17/16716/2

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

Uživatelsky definovaná agregovaná definice sum_with_reset:

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

Data

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

Výstup:

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

One-liner:

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

Postgres boolean může přetypovat true na 1, false na 0 pomocí operátoru cast ::int .

Můžete použít plpgsql jazyk také:

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

Všimněte si, že nemůžete vytvořit funkci plpgsql na sqlfiddle.com, takže tento kód plpgsql nemůžete otestovat na sqlfiddle.com. Můžete, ale na vašem počítači.



  1. Práce s JavaFX Chart API

  2. PHPExcel Render html tagy v řádku tabulky mysql

  3. Nesprávná hodnota řetězce:'\xE2\x80\xAF(fo...' pro sloupec 'description' na řádku 1 Chyba:INSERT INTO my_table_name

  4. Problémy s připojením k serveru mysql:ERROR 2003 (HY000)