-- 迁移:修复 app schema 快照视图多行膨胀 -- 背景:consumption_summary 和 assistant_customer_stats 按 stat_date 存储每日快照, -- 原视图返回全部行导致 JOIN 行膨胀和前端卡片重复。 -- 修复:DISTINCT ON 只取每个唯一键的最新 stat_date 行。 -- 日期:2026-04-08 -- 1. v_dws_member_consumption_summary:每个 member_id 只取最新快照 CREATE OR REPLACE VIEW app.v_dws_member_consumption_summary AS SELECT DISTINCT ON (member_id) id, site_id, tenant_id, member_id, stat_date, member_nickname, member_mobile, card_grade_name, register_date, first_consume_date, last_consume_date, total_visit_count, total_consume_amount, total_recharge_amount, total_table_fee, total_goods_amount, total_assistant_amount, visit_count_7d, visit_count_10d, visit_count_15d, visit_count_30d, visit_count_60d, visit_count_90d, consume_amount_7d, consume_amount_10d, consume_amount_15d, consume_amount_30d, consume_amount_60d, consume_amount_90d, cash_card_balance, gift_card_balance, total_card_balance, days_since_last, is_active_7d, is_active_30d, is_active_90d, customer_tier, created_at, updated_at, recharge_count_30d, recharge_count_60d, recharge_count_90d, recharge_amount_30d, recharge_amount_60d, recharge_amount_90d, avg_ticket_amount FROM dws.dws_member_consumption_summary WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint) ORDER BY member_id, stat_date DESC; -- 2. v_dws_assistant_customer_stats:每对 (assistant_id, member_id) 只取最新快照 CREATE OR REPLACE VIEW app.v_dws_assistant_customer_stats AS SELECT DISTINCT ON (assistant_id, member_id) id, site_id, tenant_id, assistant_id, assistant_nickname, member_id, member_nickname, member_mobile, stat_date, first_service_date, last_service_date, total_service_count, total_service_hours, total_service_amount, service_count_7d, service_count_10d, service_count_15d, service_count_30d, service_count_60d, service_count_90d, service_hours_7d, service_hours_10d, service_hours_15d, service_hours_30d, service_hours_60d, service_hours_90d, service_amount_7d, service_amount_10d, service_amount_15d, service_amount_30d, service_amount_60d, service_amount_90d, days_since_last, is_active_7d, is_active_30d, created_at, updated_at FROM dws.dws_assistant_customer_stats WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint) ORDER BY assistant_id, member_id, stat_date DESC; -- 验证 SQL(执行后检查): -- SET app.current_site_id = ''; -- 1) SELECT COUNT(*), COUNT(DISTINCT member_id) FROM app.v_dws_member_consumption_summary; -- 两个值应该相等 -- 2) SELECT COUNT(*), COUNT(DISTINCT (assistant_id, member_id)) FROM app.v_dws_assistant_customer_stats; -- 两个值应该相等 -- 3) SELECT member_id, COUNT(*) FROM app.v_dws_member_consumption_summary GROUP BY member_id HAVING COUNT(*) > 1; -- 应返回 0 行 -- 回滚: -- CREATE OR REPLACE VIEW app.v_dws_member_consumption_summary AS -- SELECT ... FROM dws.dws_member_consumption_summary WHERE (site_id = ...); -- 去掉 DISTINCT ON 和 ORDER BY -- CREATE OR REPLACE VIEW app.v_dws_assistant_customer_stats AS -- SELECT ... FROM dws.dws_assistant_customer_stats WHERE (site_id = ...); -- 同上