Files
medical-mall/pages/mall/analytics/test/07_ml_analytics_rpcs_delivery.sql
2026-03-17 11:06:26 +08:00

88 lines
2.8 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_* 口径)
-- 文件: 07_ml_analytics_rpcs_delivery.sql
-- 主题: 配送效率分析 (趋势/费用/配送员排行)
-- 依赖: public.ml_delivery_tasks, public.ml_delivery_drivers
-- 口径约定:
-- - 完成配送ml_delivery_tasks.status = 5
-- - 配送时长delivered_at - assigned_at分钟
-- - avg_feedelivery_fee 平均
-- 弃用
-- =====================================================================================
-- 1) 配送效率日趋势
-- 返回字段需匹配前端 delivery-analysis.uvueday / completed_orders / avg_delivery_minutes / avg_fee / total_fee
CREATE OR REPLACE FUNCTION public.rpc_delivery_efficiency_daily(
p_start TIMESTAMPTZ,
p_end TIMESTAMPTZ
)
RETURNS TABLE (
day TEXT,
completed_orders BIGINT,
avg_delivery_minutes NUMERIC,
avg_fee NUMERIC,
total_fee NUMERIC
)
LANGUAGE sql
AS $$
WITH date_series AS (
SELECT generate_series(date_trunc('day', p_start), date_trunc('day', p_end), interval '1 day')::date AS d
),
tasks AS (
SELECT
assigned_at::date AS d,
EXTRACT(EPOCH FROM (delivered_at - assigned_at)) / 60.0 AS minutes,
delivery_fee
FROM public.ml_delivery_tasks
WHERE status = 5
AND assigned_at IS NOT NULL
AND delivered_at IS NOT NULL
AND assigned_at >= p_start
AND assigned_at < (p_end + interval '1 second')
)
SELECT
to_char(ds.d, 'YYYY-MM-DD') AS day,
COUNT(t.minutes)::bigint AS completed_orders,
ROUND(COALESCE(AVG(t.minutes), 0)::numeric, 2) AS avg_delivery_minutes,
ROUND(COALESCE(AVG(t.delivery_fee), 0)::numeric, 2) AS avg_fee,
ROUND(COALESCE(SUM(t.delivery_fee), 0)::numeric, 2) AS total_fee
FROM date_series ds
LEFT JOIN tasks t ON t.d = ds.d
GROUP BY ds.d
ORDER BY ds.d;
$$;
-- 2) 配送员效率排行 TOP
-- 返回字段需匹配前端 delivery-analysis.uvuedriver_id / driver_name / orders / rating_avg
CREATE OR REPLACE FUNCTION public.rpc_delivery_efficiency_top_drivers(
p_start TIMESTAMPTZ,
p_end TIMESTAMPTZ,
p_limit INT DEFAULT 10
)
RETURNS TABLE (
driver_id TEXT,
driver_name TEXT,
orders BIGINT,
rating_avg NUMERIC
)
LANGUAGE sql
AS $$
SELECT
d.user_id::text AS driver_id,
COALESCE(NULLIF(u.username, ''), d.real_name, '未知')::text AS driver_name,
COUNT(t.id)::bigint AS orders,
COALESCE(d.rating_avg, 0)::numeric AS rating_avg
FROM public.ml_delivery_tasks t
JOIN public.ml_delivery_drivers d ON d.id = t.driver_id
LEFT JOIN public.ak_users u ON u.id = d.user_id
WHERE t.status = 5
AND t.assigned_at IS NOT NULL
AND t.assigned_at >= p_start
AND t.assigned_at < (p_end + interval '1 second')
GROUP BY d.user_id, u.username, d.real_name, d.rating_avg
ORDER BY orders DESC
LIMIT p_limit;
$$;