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;
|
|
|