unis_crm/sql/20260702_backfill_opportuni...

235 lines
7.4 KiB
PL/PgSQL

-- 2026-07-02 商机业绩归属地数据回填脚本
--
-- 回填规则:
-- 1. 党旭、杨斯雷:业绩归属地取商机项目地。
-- - 项目地为省级名称/简称/编码时,写入该省级 cnarea.area_code。
-- - 项目地为城市名称/简称/编码时,写入该城市上级省份 cnarea.area_code。
-- 2. 其余表格内销售:业绩归属地取表格“主区域”,写入对应省级 cnarea.area_code。
begin;
set search_path to public;
alter table if exists crm_opportunity
add column if not exists project_ownership_location varchar(100);
comment on column crm_opportunity.project_ownership_location is '业绩归属地编码,对应 cnarea.area_code';
do $$
declare
v_user_pk text;
v_name_queries text[] := array[]::text[];
v_main_region_updated integer := 0;
v_project_location_updated integer := 0;
begin
if to_regclass('public.crm_opportunity') is null then
raise exception 'crm_opportunity 表不存在,无法回填业绩归属地';
end if;
if to_regclass('public.sys_user') is null then
raise exception 'sys_user 表不存在,无法按销售负责人回填业绩归属地';
end if;
if to_regclass('public.cnarea') is null then
raise exception 'cnarea 表不存在,无法将业绩归属地解析为 area_code';
end if;
select case
when exists (
select 1
from information_schema.columns
where table_schema = 'public'
and table_name = 'sys_user'
and column_name = 'user_id'
) then 'user_id'
when exists (
select 1
from information_schema.columns
where table_schema = 'public'
and table_name = 'sys_user'
and column_name = 'id'
) then 'id'
else null
end
into v_user_pk;
if v_user_pk is null then
raise exception 'sys_user 缺少 user_id/id 字段,无法关联 crm_opportunity.owner_user_id';
end if;
if exists (
select 1
from information_schema.columns
where table_schema = 'public'
and table_name = 'sys_user'
and column_name = 'display_name'
) then
v_name_queries := array_append(
v_name_queries,
format(
'select u.%I::bigint as owner_user_id, nullif(btrim(u.display_name), '''') as owner_name from sys_user u where nullif(btrim(u.display_name), '''') is not null',
v_user_pk
)
);
end if;
if exists (
select 1
from information_schema.columns
where table_schema = 'public'
and table_name = 'sys_user'
and column_name = 'real_name'
) then
v_name_queries := array_append(
v_name_queries,
format(
'select u.%I::bigint as owner_user_id, nullif(btrim(u.real_name), '''') as owner_name from sys_user u where nullif(btrim(u.real_name), '''') is not null',
v_user_pk
)
);
end if;
if exists (
select 1
from information_schema.columns
where table_schema = 'public'
and table_name = 'sys_user'
and column_name = 'username'
) then
v_name_queries := array_append(
v_name_queries,
format(
'select u.%I::bigint as owner_user_id, nullif(btrim(u.username), '''') as owner_name from sys_user u where nullif(btrim(u.username), '''') is not null',
v_user_pk
)
);
end if;
if array_length(v_name_queries, 1) is null then
raise exception 'sys_user 缺少 display_name/real_name/username 字段,无法匹配区域销售';
end if;
drop table if exists tmp_opportunity_owner_name;
create temp table tmp_opportunity_owner_name (
owner_user_id bigint not null,
owner_name text not null
) on commit drop;
execute
'insert into tmp_opportunity_owner_name (owner_user_id, owner_name) ' ||
'select distinct owner_user_id, owner_name from (' ||
array_to_string(v_name_queries, ' union all ') ||
') t';
with owner_main_region(owner_name, main_region) as (
values
('苑磊', '山东'),
('张贝贝', '河南'),
('吕志威', '浙江'),
('谈欣', '辽宁'),
('丰世雄', '内蒙古'),
('李继设', '广西'),
('王昊玮', '山西'),
('韩东升', '云南'),
('冯文超', '湖北'),
('徐凯', '四川'),
('陈志华', '河北'),
('向往', '江苏'),
('王孟杰', '新疆'),
('杨坤融', '新疆')
)
update crm_opportunity o
set project_ownership_location = area.area_code
from tmp_opportunity_owner_name owner_name
join owner_main_region region
on region.owner_name = owner_name.owner_name
join cnarea area
on area.level = 1
and (
area.short_name = region.main_region
or area.name = region.main_region
or area.area_code = region.main_region
)
where o.owner_user_id = owner_name.owner_user_id
and o.project_ownership_location is distinct from area.area_code;
get diagnostics v_main_region_updated = row_count;
update crm_opportunity o
set project_ownership_location = (
select coalesce(
case when matched_area.level = 1 then matched_area.area_code end,
parent_area.area_code
)
from cnarea matched_area
left join cnarea parent_area
on parent_area.level = 1
and parent_area.area_code = matched_area.parent_code
where matched_area.level in (1, 2)
and (
matched_area.area_code = btrim(o.project_location)
or matched_area.short_name = btrim(o.project_location)
or matched_area.name = btrim(o.project_location)
)
order by
case when matched_area.level = 1 then 0 else 1 end,
matched_area.area_code asc,
matched_area.id asc
limit 1
)
from tmp_opportunity_owner_name owner_name
where o.owner_user_id = owner_name.owner_user_id
and owner_name.owner_name in ('党旭', '杨斯雷')
and coalesce(nullif(btrim(o.project_location), ''), '') <> ''
and (
select coalesce(
case when matched_area.level = 1 then matched_area.area_code end,
parent_area.area_code
)
from cnarea matched_area
left join cnarea parent_area
on parent_area.level = 1
and parent_area.area_code = matched_area.parent_code
where matched_area.level in (1, 2)
and (
matched_area.area_code = btrim(o.project_location)
or matched_area.short_name = btrim(o.project_location)
or matched_area.name = btrim(o.project_location)
)
order by
case when matched_area.level = 1 then 0 else 1 end,
matched_area.area_code asc,
matched_area.id asc
limit 1
) is not null
and o.project_ownership_location is distinct from (
select coalesce(
case when matched_area.level = 1 then matched_area.area_code end,
parent_area.area_code
)
from cnarea matched_area
left join cnarea parent_area
on parent_area.level = 1
and parent_area.area_code = matched_area.parent_code
where matched_area.level in (1, 2)
and (
matched_area.area_code = btrim(o.project_location)
or matched_area.short_name = btrim(o.project_location)
or matched_area.name = btrim(o.project_location)
)
order by
case when matched_area.level = 1 then 0 else 1 end,
matched_area.area_code asc,
matched_area.id asc
limit 1
);
get diagnostics v_project_location_updated = row_count;
raise notice '业绩归属地回填完成:按主区域更新 % 条,按项目地更新 % 条',
v_main_region_updated,
v_project_location_updated;
end $$;
commit;