83 lines
2.9 KiB
SQL
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).';
|
|
|