CREATE OR REPLACE PROCEDURE pro_maintain_sum(p_cur_date varchar(50))
LANGUAGE plpgsql
AS $$
DECLARE
v_cur_date date := to_date(p_cur_date, 'YYYY-MM-DD');
    v_last_date date := v_cur_date - interval '1 day';
    v_last_week_start date := v_cur_date - interval '14 days';
    v_last_week_end date := v_cur_date - interval '8 days';
    v_last_month date := v_cur_date - interval '1 month';
    v_last_year date := v_cur_date - interval '1 year';

    day_num int;
    week_num int;
    month_num int;
    year_num int;
    last_day_num int;
    last_week_num int;
    last_month_num int;
    last_year_num int;
    day_p varchar(50);
    week_p varchar(50);
    month_p varchar(50);
    year_p varchar(50);

    all_day_num int;
    all_week_num int;
    all_month_num int;
    all_year_num int;
    all_last_day_num int;
    all_last_week_num int;
    all_last_month_num int;
    all_last_year_num int;

   v_building_id varchar(50); -- 楼栋编号（添加前缀避免冲突）
BEGIN
    -- 处理各楼栋数据
FOR v_building_id IN SELECT DISTINCT id FROM building LOOP
-- 历史数据查询
SELECT COUNT(*) INTO last_day_num
FROM maintain_info
WHERE building_id = building_id
  AND cur_date::date = v_last_date;

SELECT COUNT(*) INTO last_week_num
FROM maintain_info
WHERE building_id = building_id
  AND cur_date::date BETWEEN v_last_week_start AND v_last_week_end;

SELECT COUNT(*) INTO last_month_num
FROM maintain_info
WHERE building_id = building_id
  AND date_trunc('month', cur_date) = date_trunc('month', v_last_month);

SELECT COUNT(*) INTO last_year_num
FROM maintain_info
WHERE building_id = building_id
  AND date_trunc('year', cur_date) = date_trunc('year', v_last_year);

-- 当前数据查询
SELECT COUNT(*) INTO day_num
FROM maintain_info
WHERE building_id = building_id
  AND cur_date::date = v_cur_date;

SELECT COUNT(*) INTO week_num
FROM maintain_info
WHERE building_id = building_id
  AND cur_date::date BETWEEN (v_cur_date - interval '6 days') AND v_cur_date;

SELECT COUNT(*) INTO month_num
FROM maintain_info
WHERE building_id = building_id
  AND date_trunc('month', cur_date) = date_trunc('month', v_cur_date);

SELECT COUNT(*) INTO year_num
FROM maintain_info
WHERE building_id = building_id
  AND date_trunc('year', cur_date) = date_trunc('year', v_cur_date);

-- 计算百分比
day_p := calc_percentage(day_num, last_day_num);
        week_p := calc_percentage(week_num, last_week_num);
        month_p := calc_percentage(month_num, last_month_num);
        year_p := calc_percentage(year_num, last_year_num);

        -- 插入或更新（使用UPSERT）
INSERT INTO maintain_sum AS ms
        (cur_date, building_id, day_num, day_p, week_num, week_p, month_num, month_p, year_num, year_p)
VALUES (v_cur_date, building_id, day_num, day_p, week_num, week_p, month_num, month_p, year_num, year_p)
ON CONFLICT (cur_date, building_id) DO UPDATE SET
    day_num = EXCLUDED.day_num,
                                           day_p = EXCLUDED.day_p,
                                           week_num = EXCLUDED.week_num,
                                           week_p = EXCLUDED.week_p,
                                           month_num = EXCLUDED.month_num,
                                           month_p = EXCLUDED.month_p,
                                           year_num = EXCLUDED.year_num,
                                           year_p = EXCLUDED.year_p;
END LOOP;

    -- 处理所有楼栋汇总数据
SELECT COUNT(*) INTO all_last_day_num FROM maintain_info WHERE cur_date::date = v_last_date;
SELECT COUNT(*) INTO all_last_week_num FROM maintain_info WHERE cur_date::date BETWEEN v_last_week_start AND v_last_week_end;
SELECT COUNT(*) INTO all_last_month_num FROM maintain_info WHERE date_trunc('month', cur_date) = date_trunc('month', v_last_month);
SELECT COUNT(*) INTO all_last_year_num FROM maintain_info WHERE date_trunc('year', cur_date) = date_trunc('year', v_last_year);

SELECT COUNT(*) INTO all_day_num FROM maintain_info WHERE cur_date::date = v_cur_date;
SELECT COUNT(*) INTO all_week_num FROM maintain_info WHERE cur_date::date BETWEEN (v_cur_date - interval '6 days') AND v_cur_date;
SELECT COUNT(*) INTO all_month_num FROM maintain_info WHERE date_trunc('month', cur_date) = date_trunc('month', v_cur_date);
SELECT COUNT(*) INTO all_year_num FROM maintain_info WHERE date_trunc('year', cur_date) = date_trunc('year', v_cur_date);

-- 计算百分比（可复用函数）
day_p := calc_percentage(all_day_num, all_last_day_num);
    week_p := calc_percentage(all_week_num, all_last_week_num);
    month_p := calc_percentage(all_month_num, all_last_month_num);
    year_p := calc_percentage(all_year_num, all_last_year_num);

    -- 使用UPSERT处理汇总数据
INSERT INTO maintain_sum AS ms
    (cur_date, building_id, day_num, day_p, week_num, week_p, month_num, month_p, year_num, year_p)
VALUES (v_cur_date, '所有', all_day_num, day_p, all_week_num, week_p, all_month_num, month_p, all_year_num, year_p)
ON CONFLICT (cur_date, building_id) DO UPDATE SET
    day_num = EXCLUDED.day_num,
                                           day_p = EXCLUDED.day_p,
                                           week_num = EXCLUDED.week_num,
                                           week_p = EXCLUDED.week_p,
                                           month_num = EXCLUDED.month_num,
                                           month_p = EXCLUDED.month_p,
                                           year_num = EXCLUDED.year_num,
                                           year_p = EXCLUDED.year_p;
END;
$$;

-- 创建百分比计算函数
CREATE OR REPLACE FUNCTION calc_percentage(current_val int, last_val int)
RETURNS varchar(50) AS $$
BEGIN
RETURN CASE
           WHEN last_val > 0 THEN
               ROUND(((current_val - last_val)::numeric / last_val * 100)::numeric, 2) || '%'
           ELSE '0%'
    END;
END;
$$ LANGUAGE plpgsql;
