Files
ems/db/routines/R__081_fn_ote_day_brief_prague.sql
Dusan Vojacek 6074535d96
Some checks failed
CI and deploy / migration-check (push) Failing after 25s
CI and deploy / deploy (push) Has been skipped
OTE informatin discord
2026-04-29 14:17:24 +02:00

83 lines
2.9 KiB
SQL

-- OTE CZ: stručná analýza cen pro den (TZ Europe/Prague)
create or replace function ems.fn_ote_day_brief_prague(p_day date)
returns jsonb
language sql
stable
as $fn$
with slots as (
select
mip.interval_start,
mip.buy_raw_price_czk_kwh as price,
(mip.interval_start at time zone 'Europe/Prague') as local_ts,
extract(hour from mip.interval_start at time zone 'Europe/Prague')::int as local_hour
from ems.market_interval_price mip
where mip.market_source = 'OTE_CZ'
and (mip.interval_start at time zone 'Europe/Prague')::date = p_day
),
agg as (
select
count(*)::int as slot_count,
min(price) as min_price,
max(price) as max_price,
avg(price) as avg_price,
count(*) filter (where price < 0)::int as negative_slots,
count(*) filter (where abs(price) <= 0.25)::int as zeroish_slots
from slots
),
min_slot as (
select s.local_ts, s.local_hour, s.price
from slots s
order by s.price asc, s.local_ts asc
limit 1
),
max_slot as (
select s.local_ts, s.local_hour, s.price
from slots s
order by s.price desc, s.local_ts asc
limit 1
),
noon as (
select
min(price) as noon_min_price,
avg(price) as noon_avg_price
from slots
where local_hour between 10 and 14
),
morning as (
select
max(price) as morning_max_price,
avg(price) as morning_avg_price
from slots
where local_hour between 6 and 9
),
evening as (
select
max(price) as evening_max_price,
avg(price) as evening_avg_price
from slots
where local_hour between 17 and 21
)
select jsonb_build_object(
'day', p_day,
'slot_count', (select slot_count from agg),
'is_complete', (select slot_count from agg) in (92, 96, 100),
'min_price', round(coalesce((select min_price from agg), 0)::numeric, 6),
'max_price', round(coalesce((select max_price from agg), 0)::numeric, 6),
'avg_price', round(coalesce((select avg_price from agg), 0)::numeric, 6),
'negative_slots', (select negative_slots from agg),
'zeroish_slots', (select zeroish_slots from agg),
'min_slot_local', (select local_ts from min_slot),
'max_slot_local', (select local_ts from max_slot),
'noon_min_price', round(coalesce((select noon_min_price from noon), 0)::numeric, 6),
'noon_avg_price', round(coalesce((select noon_avg_price from noon), 0)::numeric, 6),
'morning_max_price', round(coalesce((select morning_max_price from morning), 0)::numeric, 6),
'morning_avg_price', round(coalesce((select morning_avg_price from morning), 0)::numeric, 6),
'evening_max_price', round(coalesce((select evening_max_price from evening), 0)::numeric, 6)
);
$fn$;
comment on function ems.fn_ote_day_brief_prague(date) is
'Stručná analýza OTE_CZ cen pro den v Europe/Prague (min/max/avg, podíl záporných/okolo nuly, poledne/rano/vecer).';