-- ============================================
-- 创建会员开单耗卡项目数视图
-- ============================================
-- 说明：创建视图可以提升查询效率，避免每次都执行复杂的JOIN和聚合操作
-- 视图会预先聚合好数据，查询时直接使用

-- ============================================
-- 方案1：基础聚合视图（推荐）
-- ============================================
-- 优点：查询简单、性能好、可以灵活按时间范围查询
-- 缺点：仍然需要每次查询时过滤时间范围

-- 删除已存在的视图（如果存在）
DROP VIEW IF EXISTS v_member_billing_consume_project;

-- 创建视图：会员开单项目数汇总（不限制时间，包含所有数据）
CREATE VIEW v_member_billing_project AS
SELECT 
    px.F_MemberId as member_id,
    kd.djmd as store_id,
    kd.kdrq as billing_date,
    SUM(CAST(px.F_ProjectNumber AS DECIMAL(18,2))) as billing_project_count
FROM lq_kd_pxmx px
INNER JOIN lq_kd_kdjlb kd ON px.glkdbh = kd.F_Id
WHERE px.F_IsEffective = 1
    AND kd.F_IsEffective = 1
    AND px.F_MemberId IS NOT NULL
    AND px.F_MemberId != ''
GROUP BY px.F_MemberId, kd.djmd, DATE(kd.kdrq);

-- 创建视图：会员耗卡项目数汇总（不限制时间，包含所有数据）
CREATE VIEW v_member_consume_project AS
SELECT 
    xhpx.F_MemberId as member_id,
    xh.md as store_id,
    xh.hksj as consume_date,
    SUM(CAST(xhpx.F_ProjectNumber AS DECIMAL(18,2))) as consume_project_count
FROM lq_xh_pxmx xhpx
INNER JOIN lq_xh_hyhk xh ON xhpx.F_ConsumeInfoId = xh.F_Id
WHERE xhpx.F_IsEffective = 1
    AND xh.F_IsEffective = 1
    AND xhpx.F_MemberId IS NOT NULL
    AND xhpx.F_MemberId != ''
GROUP BY xhpx.F_MemberId, xh.md, DATE(xh.hksj);

-- 创建组合视图：会员开单耗卡项目数（按日汇总）
CREATE VIEW v_member_billing_consume_daily AS
SELECT 
    COALESCE(billing.member_id, consume.member_id) as member_id,
    COALESCE(billing.store_id, consume.store_id) as store_id,
    COALESCE(billing.billing_date, consume.consume_date) as statistics_date,
    COALESCE(billing.billing_project_count, 0) as billing_project_count,
    COALESCE(consume.consume_project_count, 0) as consume_project_count,
    (COALESCE(billing.billing_project_count, 0) - COALESCE(consume.consume_project_count, 0)) as remaining_project_count
FROM v_member_billing_project billing
FULL OUTER JOIN v_member_consume_project consume 
    ON billing.member_id = consume.member_id 
    AND billing.store_id = consume.store_id
    AND DATE(billing.billing_date) = DATE(consume.consume_date);

-- ============================================
-- 方案2：使用UNION ALL的视图（兼容MySQL，推荐）
-- ============================================
-- 优点：兼容MySQL所有版本、查询简单、性能好

DROP VIEW IF EXISTS v_member_billing_consume_project;

CREATE VIEW v_member_billing_consume_project AS
SELECT 
    member_id,
    store_id,
    statistics_date,
    SUM(billing_project_count) as billing_project_count,
    SUM(consume_project_count) as consume_project_count,
    SUM(billing_project_count) - SUM(consume_project_count) as remaining_project_count
FROM (
    -- 开单项目数（按会员、门店、日期分组）
    SELECT 
        px.F_MemberId as member_id,
        kd.djmd as store_id,
        DATE(kd.kdrq) as statistics_date,
        SUM(CAST(px.F_ProjectNumber AS DECIMAL(18,2))) as billing_project_count,
        0 as consume_project_count
    FROM lq_kd_pxmx px
    INNER JOIN lq_kd_kdjlb kd ON px.glkdbh = kd.F_Id
    WHERE px.F_IsEffective = 1
        AND kd.F_IsEffective = 1
        AND px.F_MemberId IS NOT NULL
        AND px.F_MemberId != ''
    GROUP BY px.F_MemberId, kd.djmd, DATE(kd.kdrq)
    
    UNION ALL
    
    -- 耗卡项目数（按会员、门店、日期分组）
    SELECT 
        xhpx.F_MemberId as member_id,
        xh.md as store_id,
        DATE(xh.hksj) as statistics_date,
        0 as billing_project_count,
        SUM(CAST(xhpx.F_ProjectNumber AS DECIMAL(18,2))) as consume_project_count
    FROM lq_xh_pxmx xhpx
    INNER JOIN lq_xh_hyhk xh ON xhpx.F_ConsumeInfoId = xh.F_Id
    WHERE xhpx.F_IsEffective = 1
        AND xh.F_IsEffective = 1
        AND xhpx.F_MemberId IS NOT NULL
        AND xhpx.F_MemberId != ''
    GROUP BY xhpx.F_MemberId, xh.md, DATE(xh.hksj)
) all_data
GROUP BY member_id, store_id, statistics_date;

-- ============================================
-- 方案3：按会员汇总的总视图（不按日期，累计汇总）
-- ============================================
-- 优点：查询最简单、性能最好（适合查询总量）
-- 缺点：无法按时间范围查询

DROP VIEW IF EXISTS v_member_billing_consume_total;

CREATE VIEW v_member_billing_consume_total AS
SELECT 
    member_id,
    SUM(billing_project_count) as total_billing_project_count,
    SUM(consume_project_count) as total_consume_project_count,
    SUM(billing_project_count) - SUM(consume_project_count) as total_remaining_project_count,
    COUNT(DISTINCT store_id) as store_count
FROM (
    -- 开单项目数（按会员、门店汇总）
    SELECT 
        px.F_MemberId as member_id,
        kd.djmd as store_id,
        SUM(CAST(px.F_ProjectNumber AS DECIMAL(18,2))) as billing_project_count,
        0 as consume_project_count
    FROM lq_kd_pxmx px
    INNER JOIN lq_kd_kdjlb kd ON px.glkdbh = kd.F_Id
    WHERE px.F_IsEffective = 1
        AND kd.F_IsEffective = 1
        AND px.F_MemberId IS NOT NULL
        AND px.F_MemberId != ''
    GROUP BY px.F_MemberId, kd.djmd
    
    UNION ALL
    
    -- 耗卡项目数（按会员、门店汇总）
    SELECT 
        xhpx.F_MemberId as member_id,
        xh.md as store_id,
        0 as billing_project_count,
        SUM(CAST(xhpx.F_ProjectNumber AS DECIMAL(18,2))) as consume_project_count
    FROM lq_xh_pxmx xhpx
    INNER JOIN lq_xh_hyhk xh ON xhpx.F_ConsumeInfoId = xh.F_Id
    WHERE xhpx.F_IsEffective = 1
        AND xh.F_IsEffective = 1
        AND xhpx.F_MemberId IS NOT NULL
        AND xhpx.F_MemberId != ''
    GROUP BY xhpx.F_MemberId, xh.md
) all_data
GROUP BY member_id;


-- ============================================
-- 使用视图的查询示例
-- ============================================

-- 示例1：查询所有会员的开单耗卡项目数（按会员汇总，不限制时间）
SELECT 
    member_id,
    SUM(billing_project_count) as billing_project_count,
    SUM(consume_project_count) as consume_project_count,
    SUM(remaining_project_count) as remaining_project_count
FROM v_member_billing_consume_project
GROUP BY member_id
ORDER BY billing_project_count DESC;

-- 示例2：查询指定时间范围内的数据
SELECT 
    member_id,
    SUM(billing_project_count) as billing_project_count,
    SUM(consume_project_count) as consume_project_count,
    SUM(remaining_project_count) as remaining_project_count
FROM v_member_billing_consume_project
WHERE statistics_date >= '2025-10-01'
    AND statistics_date <= '2025-10-30'
GROUP BY member_id
ORDER BY billing_project_count DESC;

-- 示例3：查询指定门店的数据
SELECT 
    member_id,
    SUM(billing_project_count) as billing_project_count,
    SUM(consume_project_count) as consume_project_count,
    SUM(remaining_project_count) as remaining_project_count
FROM v_member_billing_consume_project
WHERE store_id = '1649328471923847169'
    AND statistics_date >= '2025-10-01'
    AND statistics_date <= '2025-10-30'
GROUP BY member_id
ORDER BY billing_project_count DESC;

-- 示例4：使用总视图（最简单的查询，累计所有数据）
SELECT 
    member_id,
    total_billing_project_count,
    total_consume_project_count,
    total_remaining_project_count,
    store_count
FROM v_member_billing_consume_total
ORDER BY total_billing_project_count DESC
LIMIT 100;


-- ============================================
-- 视图性能优化建议
-- ============================================
-- 1. 确保基础表已创建索引（参考优化GetStoreRemainingRights性能索引.sql）
-- 2. 如果数据量很大，可以考虑：
--    a. 创建物化视图（但MySQL不支持，需要定期刷新汇总表）
--    b. 创建汇总表，定期更新（推荐）
-- 3. 定期分析视图性能：
--    EXPLAIN SELECT * FROM v_member_billing_consume_project WHERE statistics_date >= '2025-10-01';

-- ============================================
-- 视图维护
-- ============================================
-- 查看视图定义
-- SHOW CREATE VIEW v_member_billing_consume_project;

-- 查看所有视图
-- SELECT TABLE_NAME 
-- FROM INFORMATION_SCHEMA.VIEWS 
-- WHERE TABLE_SCHEMA = DATABASE();

-- 删除视图
-- DROP VIEW IF EXISTS v_member_billing_consume_project;
-- DROP VIEW IF EXISTS v_member_billing_consume_total;

