高效能源监控管理系统
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

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;