Files
medical-mall/pages/mall/analytics/test/03_ml_analytics_rpcs_dashboard.sql
2026-01-31 21:47:42 +08:00

77 lines
3.3 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =====================================================================================
-- 数据分析模块正式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';
$$;