数据分析ui补充完善,接入数据库
This commit is contained in:
183
pages/mall/analytics/test/06_ml_analytics_rpcs_coupon.sql
Normal file
183
pages/mall/analytics/test/06_ml_analytics_rpcs_coupon.sql
Normal file
@@ -0,0 +1,183 @@
|
||||
-- =====================================================================================
|
||||
-- 数据分析模块(正式RPC,主库 ml_* 口径)
|
||||
-- 文件: 06_ml_analytics_rpcs_coupon.sql
|
||||
-- 主题: 优惠券效果分析 (概览/类型/渠道/趋势/转化)
|
||||
-- 依赖: public.ml_coupon_templates, public.ml_user_coupons, public.ml_orders
|
||||
-- =====================================================================================
|
||||
|
||||
-- 1) 优惠券分析核心 KPI
|
||||
CREATE OR REPLACE FUNCTION public.rpc_analytics_coupon_overview(
|
||||
p_start_date DATE,
|
||||
p_end_date DATE
|
||||
)
|
||||
RETURNS TABLE (
|
||||
total_issued BIGINT,
|
||||
issued_growth FLOAT,
|
||||
total_used BIGINT,
|
||||
usage_rate FLOAT,
|
||||
gmv_increase NUMERIC,
|
||||
gmv_growth FLOAT,
|
||||
roi FLOAT
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
prev_start_date DATE;
|
||||
prev_end_date DATE;
|
||||
period_days INT;
|
||||
BEGIN
|
||||
period_days := p_end_date - p_start_date + 1;
|
||||
prev_start_date := p_start_date - period_days;
|
||||
prev_end_date := p_start_date - 1;
|
||||
|
||||
RETURN QUERY
|
||||
WITH
|
||||
cur AS (
|
||||
SELECT
|
||||
COUNT(uc.id) AS total_issued,
|
||||
COUNT(CASE WHEN uc.status = 2 THEN uc.id END) AS total_used,
|
||||
COALESCE(SUM(o.total_amount), 0) AS gmv_increase
|
||||
FROM public.ml_user_coupons uc
|
||||
LEFT JOIN public.ml_orders o ON uc.order_id = o.id
|
||||
WHERE uc.received_at::date BETWEEN p_start_date AND p_end_date
|
||||
),
|
||||
prev AS (
|
||||
SELECT
|
||||
COUNT(uc.id) AS total_issued,
|
||||
COALESCE(SUM(o.total_amount), 0) AS gmv_increase
|
||||
FROM public.ml_user_coupons uc
|
||||
LEFT JOIN public.ml_orders o ON uc.order_id = o.id
|
||||
WHERE uc.received_at::date BETWEEN prev_start_date AND prev_end_date
|
||||
)
|
||||
SELECT
|
||||
c.total_issued,
|
||||
ROUND(((c.total_issued - p.total_issued) * 100.0 / NULLIF(p.total_issued, 0))::numeric, 2)::FLOAT AS issued_growth,
|
||||
c.total_used,
|
||||
ROUND((c.total_used * 100.0 / NULLIF(c.total_issued, 0))::numeric, 2)::FLOAT AS usage_rate,
|
||||
c.gmv_increase,
|
||||
ROUND(((c.gmv_increase - p.gmv_increase) * 100.0 / NULLIF(p.gmv_increase, 0))::numeric, 2)::FLOAT AS gmv_growth,
|
||||
-- ROI 简化为 GMV提升 / 优惠券总面值,这里缺少面值,暂时返回0
|
||||
0.0::FLOAT AS roi
|
||||
FROM cur c, prev p;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
-- 2) 按优惠券类型分析
|
||||
CREATE OR REPLACE FUNCTION public.rpc_analytics_coupon_by_type(
|
||||
p_start_date DATE,
|
||||
p_end_date DATE
|
||||
)
|
||||
RETURNS TABLE (
|
||||
coupon_type INT,
|
||||
total_issued BIGINT,
|
||||
total_used BIGINT,
|
||||
usage_rate FLOAT
|
||||
)
|
||||
LANGUAGE sql
|
||||
AS $$
|
||||
SELECT
|
||||
t.coupon_type,
|
||||
COUNT(uc.id)::BIGINT AS total_issued,
|
||||
COUNT(CASE WHEN uc.status = 2 THEN uc.id END)::BIGINT AS total_used,
|
||||
ROUND((COUNT(CASE WHEN uc.status = 2 THEN uc.id END) * 100.0 / COUNT(uc.id))::numeric, 2)::FLOAT AS usage_rate
|
||||
FROM public.ml_user_coupons uc
|
||||
JOIN public.ml_coupon_templates t ON uc.template_id = t.id
|
||||
WHERE uc.received_at::date BETWEEN p_start_date AND p_end_date
|
||||
GROUP BY t.coupon_type;
|
||||
$$;
|
||||
|
||||
|
||||
-- 3) 按发放渠道分析
|
||||
-- 注意: ml_user_coupons 表缺少 'source' 或 'channel' 字段,这里返回模拟数据
|
||||
CREATE OR REPLACE FUNCTION public.rpc_analytics_coupon_by_channel(
|
||||
p_start_date DATE,
|
||||
p_end_date DATE
|
||||
)
|
||||
RETURNS TABLE (
|
||||
channel TEXT,
|
||||
total_issued BIGINT,
|
||||
total_used BIGINT
|
||||
)
|
||||
LANGUAGE sql
|
||||
AS $$
|
||||
SELECT * FROM (VALUES
|
||||
('manual', 150, 60),
|
||||
('auto', 300, 120),
|
||||
('campaign', 500, 250),
|
||||
('invite', 80, 40),
|
||||
('cs', 20, 15),
|
||||
('points', 120, 50)
|
||||
) AS t(channel, total_issued, total_used);
|
||||
$$;
|
||||
|
||||
|
||||
-- 4) 优惠券使用趋势 (按天)
|
||||
CREATE OR REPLACE FUNCTION public.rpc_analytics_coupon_trend(
|
||||
p_start_date DATE,
|
||||
p_end_date DATE
|
||||
)
|
||||
RETURNS TABLE (
|
||||
day TEXT,
|
||||
issued BIGINT,
|
||||
used BIGINT
|
||||
)
|
||||
LANGUAGE sql
|
||||
AS $$
|
||||
WITH date_series AS (
|
||||
SELECT generate_series(p_start_date, p_end_date, '1 day'::interval)::date AS d
|
||||
)
|
||||
SELECT
|
||||
to_char(ds.d, 'YYYY-MM-DD') AS day,
|
||||
(SELECT COUNT(id) FROM public.ml_user_coupons WHERE received_at::date = ds.d) AS issued,
|
||||
(SELECT COUNT(id) FROM public.ml_user_coupons WHERE used_at::date = ds.d) AS used
|
||||
FROM date_series ds
|
||||
ORDER BY ds.d;
|
||||
$$;
|
||||
|
||||
|
||||
-- 5) 优惠券转化效果对比
|
||||
CREATE OR REPLACE FUNCTION public.rpc_analytics_coupon_conversion(
|
||||
p_start_date DATE,
|
||||
p_end_date DATE
|
||||
)
|
||||
RETURNS TABLE (
|
||||
metric TEXT,
|
||||
with_coupon NUMERIC,
|
||||
without_coupon NUMERIC
|
||||
)
|
||||
LANGUAGE sql
|
||||
AS $$
|
||||
WITH orders_with_coupon AS (
|
||||
SELECT
|
||||
SUM(o.total_amount) AS gmv,
|
||||
COUNT(o.id) AS orders
|
||||
FROM public.ml_orders o
|
||||
WHERE o.created_at::date BETWEEN p_start_date AND p_end_date
|
||||
AND o.payment_status = 2
|
||||
AND o.discount_amount > 0 -- 简化判断:有优惠金额即认为用了券
|
||||
),
|
||||
orders_without_coupon AS (
|
||||
SELECT
|
||||
SUM(o.total_amount) AS gmv,
|
||||
COUNT(o.id) AS orders
|
||||
FROM public.ml_orders o
|
||||
WHERE o.created_at::date BETWEEN p_start_date AND p_end_date
|
||||
AND o.payment_status = 2
|
||||
AND o.discount_amount = 0
|
||||
)
|
||||
SELECT
|
||||
'GMV' AS metric,
|
||||
(SELECT gmv FROM orders_with_coupon) AS with_coupon,
|
||||
(SELECT gmv FROM orders_without_coupon) AS without_coupon
|
||||
UNION ALL
|
||||
SELECT
|
||||
'orders' AS metric,
|
||||
(SELECT orders FROM orders_with_coupon) AS with_coupon,
|
||||
(SELECT orders FROM orders_without_coupon) AS without_coupon
|
||||
UNION ALL
|
||||
SELECT
|
||||
'avg_order_amount' AS metric,
|
||||
(SELECT gmv / NULLIF(orders, 0) FROM orders_with_coupon) AS with_coupon,
|
||||
(SELECT gmv / NULLIF(orders, 0) FROM orders_without_coupon) AS without_coupon;
|
||||
$$;
|
||||
Reference in New Issue
Block a user