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