-- ===================================================================================== -- 数据分析模块(正式RPC,主库 ml_* 口径) -- 文件: 03_ml_analytics_rpcs_dashboard.sql -- 主题: 仪表盘实时指标 (GMV/订单/在线用户/转化率) -- ===================================================================================== -- 1) 仪表盘实时核心 KPI (今日 vs 昨日同刻) CREATE OR REPLACE FUNCTION public.rpc_analytics_realtime_kpis() RETURNS TABLE ( gmv NUMERIC, gmv_growth FLOAT, orders BIGINT, order_growth FLOAT, conversion_rate FLOAT, conversion_growth FLOAT ) LANGUAGE plpgsql AS $$ DECLARE today_start timestamptz := date_trunc('day', now()); yesterday_start timestamptz := today_start - interval '1 day'; yesterday_equivalent timestamptz := now() - interval '1 day'; BEGIN RETURN QUERY WITH -- 今日实时数据 today AS ( SELECT COALESCE(SUM(CASE WHEN o.payment_status = 2 THEN COALESCE(NULLIF(o.paid_amount, 0), o.total_amount) ELSE 0 END), 0) AS gmv, COUNT(o.id)::BIGINT AS orders, (SELECT COUNT(DISTINCT user_id) FROM public.ml_orders WHERE created_at >= today_start AND payment_status = 2) AS paid_users, (SELECT COUNT(DISTINCT user_id) FROM public.ml_browse_history WHERE created_at >= today_start) AS active_users FROM public.ml_orders o WHERE o.created_at >= today_start ), -- 昨日同期数据 yesterday AS ( SELECT COALESCE(SUM(CASE WHEN o.payment_status = 2 THEN COALESCE(NULLIF(o.paid_amount, 0), o.total_amount) ELSE 0 END), 0) AS gmv, COUNT(o.id)::BIGINT AS orders, (SELECT COUNT(DISTINCT user_id) FROM public.ml_orders WHERE created_at BETWEEN yesterday_start AND yesterday_equivalent AND payment_status = 2) AS paid_users, (SELECT COUNT(DISTINCT user_id) FROM public.ml_browse_history WHERE created_at BETWEEN yesterday_start AND yesterday_equivalent) AS active_users FROM public.ml_orders o WHERE o.created_at BETWEEN yesterday_start AND yesterday_equivalent ), calc AS ( SELECT t.gmv, y.gmv AS prev_gmv, t.orders, y.orders AS prev_orders, CASE WHEN t.active_users > 0 THEN (t.paid_users::NUMERIC / t.active_users) * 100 ELSE 0 END AS conversion_rate, CASE WHEN y.active_users > 0 THEN (y.paid_users::NUMERIC / y.active_users) * 100 ELSE 0 END AS prev_conversion_rate FROM today t, yesterday y ) SELECT ROUND(c.gmv, 2) AS gmv, ROUND(((c.gmv - c.prev_gmv) * 100.0 / NULLIF(c.prev_gmv, 0))::numeric, 2)::FLOAT AS gmv_growth, c.orders, ROUND(((c.orders - c.prev_orders) * 100.0 / NULLIF(c.prev_orders, 0))::numeric, 2)::FLOAT AS order_growth, ROUND(c.conversion_rate::numeric, 2)::FLOAT AS conversion_rate, ROUND((c.conversion_rate - c.prev_conversion_rate)::numeric, 2)::FLOAT AS conversion_growth FROM calc c; END; $$; -- 2) 在线用户数 (基于最近5分钟的浏览历史) CREATE OR REPLACE FUNCTION public.rpc_analytics_online_users() RETURNS BIGINT LANGUAGE sql AS $$ SELECT COUNT(DISTINCT user_id)::BIGINT FROM public.ml_browse_history WHERE created_at >= now() - INTERVAL '5 minutes'; $$;