You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							144 lines
						
					
					
						
							5.8 KiB
						
					
					
				
			
		
		
	
	
							144 lines
						
					
					
						
							5.8 KiB
						
					
					
				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;
 | 
						|
 |