88 lines
2.8 KiB
PL/PgSQL
88 lines
2.8 KiB
PL/PgSQL
-- =====================================================================================
|
||
-- 数据分析模块(正式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_fee:delivery_fee 平均
|
||
|
||
-- 弃用
|
||
-- =====================================================================================
|
||
|
||
-- 1) 配送效率日趋势
|
||
-- 返回字段需匹配前端 delivery-analysis.uvue:day / 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.uvue:driver_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;
|
||
$$;
|