Clickhouse: Остатки на каждый день

Created on 22 Oct 2018  ·  4Comments  ·  Source: ClickHouse/ClickHouse

Необходимо посчитать остаток на каждую дату из периода, если в какой-то день не было движения, то брать остаток предыдущего дня. Можно ли получить такие данные запросом в ClickHouse?

question

Most helpful comment

Можно ли получить такие данные запросом в ClickHouse?

в общем случае нельзя, КХ не умеет window functions.

Чисто так по приколу:

create table transactions(acc String, d DateTime, amount Float64) Engine = MergeTree partition by toYYYYMM(d) order by (acc,d);

insert into transactions values('a1', now(), 5), ('a1', now()-100, 5), ('a1', now()-3600*24*4-100, -2), ('a2', now()-3600*2*24-100, 1), ('a2', now(), 1);

select acc, toDate(d) dt, sum(amount)
from transactions
group by acc, dt
order by acc, dt;
┌─acc─┬─────────dt─┬─sum(amount)─┐
│ a1  │ 2018-10-18 │          -2 │
│ a1  │ 2018-10-22 │          10 │
│ a2  │ 2018-10-20 │           1 │
│ a2  │ 2018-10-22 │           1 │
└─────┴────────────┴─────────────┘

select  * from (
select acc, groupArray(dt) `t.dt`, arrayCumSum(groupArray(samount)) `t.amm`  from (
select acc, dt, samount
from (select today()-number dt, acc from numbers(8) cross join (select distinct acc from transactions)) 
   all left  join (select acc, toDate(d) dt, sum(amount) samount from transactions group by acc, dt) using acc,dt
order by acc, dt) group by acc) Array Join t;

┌─acc─┬───────t.dt─┬─t.amm─┐
│ a1  │ 2018-10-15 │     0 │
│ a1  │ 2018-10-16 │     0 │
│ a1  │ 2018-10-17 │     0 │
│ a1  │ 2018-10-18 │    -2 │
│ a1  │ 2018-10-19 │    -2 │
│ a1  │ 2018-10-20 │    -2 │
│ a1  │ 2018-10-21 │    -2 │
│ a1  │ 2018-10-22 │     8 │
│ a2  │ 2018-10-15 │     0 │
│ a2  │ 2018-10-16 │     0 │
│ a2  │ 2018-10-17 │     0 │
│ a2  │ 2018-10-18 │     0 │
│ a2  │ 2018-10-19 │     0 │
│ a2  │ 2018-10-20 │     1 │
│ a2  │ 2018-10-21 │     1 │
│ a2  │ 2018-10-22 │     2 │
└─────┴────────────┴───────┘

All 4 comments

Давайте пример таблицы, данных в ней, и что хотите получить в итоге. Попробуем придумать запрос.

Можно ли получить такие данные запросом в ClickHouse?

в общем случае нельзя, КХ не умеет window functions.

Чисто так по приколу:

create table transactions(acc String, d DateTime, amount Float64) Engine = MergeTree partition by toYYYYMM(d) order by (acc,d);

insert into transactions values('a1', now(), 5), ('a1', now()-100, 5), ('a1', now()-3600*24*4-100, -2), ('a2', now()-3600*2*24-100, 1), ('a2', now(), 1);

select acc, toDate(d) dt, sum(amount)
from transactions
group by acc, dt
order by acc, dt;
┌─acc─┬─────────dt─┬─sum(amount)─┐
│ a1  │ 2018-10-18 │          -2 │
│ a1  │ 2018-10-22 │          10 │
│ a2  │ 2018-10-20 │           1 │
│ a2  │ 2018-10-22 │           1 │
└─────┴────────────┴─────────────┘

select  * from (
select acc, groupArray(dt) `t.dt`, arrayCumSum(groupArray(samount)) `t.amm`  from (
select acc, dt, samount
from (select today()-number dt, acc from numbers(8) cross join (select distinct acc from transactions)) 
   all left  join (select acc, toDate(d) dt, sum(amount) samount from transactions group by acc, dt) using acc,dt
order by acc, dt) group by acc) Array Join t;

┌─acc─┬───────t.dt─┬─t.amm─┐
│ a1  │ 2018-10-15 │     0 │
│ a1  │ 2018-10-16 │     0 │
│ a1  │ 2018-10-17 │     0 │
│ a1  │ 2018-10-18 │    -2 │
│ a1  │ 2018-10-19 │    -2 │
│ a1  │ 2018-10-20 │    -2 │
│ a1  │ 2018-10-21 │    -2 │
│ a1  │ 2018-10-22 │     8 │
│ a2  │ 2018-10-15 │     0 │
│ a2  │ 2018-10-16 │     0 │
│ a2  │ 2018-10-17 │     0 │
│ a2  │ 2018-10-18 │     0 │
│ a2  │ 2018-10-19 │     0 │
│ a2  │ 2018-10-20 │     1 │
│ a2  │ 2018-10-21 │     1 │
│ a2  │ 2018-10-22 │     2 │
└─────┴────────────┴───────┘

Если взять таблицу из ответа выше
┌acc┬──────dt─┬─sum─┐
│ a1 │ 2018-10-18 │ -2 │
│ a1 │ 2018-10-22 │ 10 │
│ a2 │ 2018-10-20 │ 1 │
│ a2 │ 2018-10-22 │ 1 │
└──┴────────┴─────┘
то за период с 17,10,18 по 22,10,18 должны получиться сл. данные:
┬──────dt─┬sum─┐
│ 2018-10-17 │ 0 │
│ 2018-10-18 │ -2 │
│ 2018-10-19 │ -2 │
│ 2018-10-20 │ 1 │
│ 2018-10-21 │ 1 │
│ 2018-10-22 │ 11 │
└────────┴───┘

календарь - просто список дат попавших в требуемый период.

Was this page helpful?
0 / 5 - 0 ratings