Files
ccdi/sql/migration/2026-03-19-backfill-staff-income-and-relatives.sql
2026-03-19 16:11:32 +08:00

307 lines
8.4 KiB
SQL

START TRANSACTION;
-- 1. 为尚未维护年收入的员工补齐收入
UPDATE ccdi_base_staff
SET annual_income = ROUND(
120000
+ MOD(staff_id, 9) * 18000
+ MOD(staff_id, 5) * 2500,
2
),
update_by = 'system',
update_time = NOW()
WHERE annual_income IS NULL;
-- 2. 保留已与资产关联的员工亲属关系,避免资产详情失联
DROP TEMPORARY TABLE IF EXISTS tmp_staff_family_preserved;
CREATE TEMPORARY TABLE tmp_staff_family_preserved AS
SELECT
r.person_id,
r.relation_type,
r.relation_name,
r.gender,
r.birth_date,
r.relation_cert_type,
r.relation_cert_no,
r.mobile_phone1,
r.mobile_phone2,
r.annual_income,
r.wechat_no1,
r.wechat_no2,
r.wechat_no3,
r.contact_address,
r.relation_desc,
r.effective_date,
r.invalid_date,
1 AS status,
r.remark,
COALESCE(NULLIF(r.data_source, ''), 'SYSTEM') AS data_source,
1 AS is_emp_family,
0 AS is_cust_family,
COALESCE(NULLIF(r.created_by, ''), 'system') AS created_by,
COALESCE(NULLIF(r.updated_by, ''), 'system') AS updated_by
FROM ccdi_staff_fmy_relation r
WHERE r.is_emp_family = 1
AND EXISTS (
SELECT 1
FROM ccdi_asset_info a
WHERE a.family_id = r.person_id
AND a.person_id = r.relation_cert_no
);
DROP TEMPORARY TABLE IF EXISTS tmp_staff_family_preserved_count;
CREATE TEMPORARY TABLE tmp_staff_family_preserved_count AS
SELECT person_id, COUNT(*) AS preserved_count
FROM tmp_staff_family_preserved
GROUP BY person_id;
-- 3. 清理旧员工亲属数据,按当前员工主数据重建每人 1-3 个亲属
DELETE FROM ccdi_staff_fmy_relation
WHERE is_emp_family = 1;
INSERT INTO ccdi_staff_fmy_relation (
person_id,
relation_type,
relation_name,
gender,
birth_date,
relation_cert_type,
relation_cert_no,
mobile_phone1,
mobile_phone2,
annual_income,
wechat_no1,
wechat_no2,
wechat_no3,
contact_address,
relation_desc,
effective_date,
invalid_date,
status,
remark,
data_source,
is_emp_family,
is_cust_family,
created_by,
create_time,
updated_by,
update_time
)
SELECT
person_id,
relation_type,
relation_name,
gender,
birth_date,
relation_cert_type,
relation_cert_no,
mobile_phone1,
mobile_phone2,
annual_income,
wechat_no1,
wechat_no2,
wechat_no3,
contact_address,
relation_desc,
COALESCE(effective_date, NOW()),
NULL,
status,
remark,
data_source,
is_emp_family,
is_cust_family,
created_by,
NOW(),
updated_by,
NOW()
FROM tmp_staff_family_preserved;
INSERT INTO ccdi_staff_fmy_relation (
person_id,
relation_type,
relation_name,
gender,
birth_date,
relation_cert_type,
relation_cert_no,
mobile_phone1,
mobile_phone2,
annual_income,
wechat_no1,
wechat_no2,
wechat_no3,
contact_address,
relation_desc,
effective_date,
invalid_date,
status,
remark,
data_source,
is_emp_family,
is_cust_family,
created_by,
create_time,
updated_by,
update_time
)
SELECT
relation_gen.person_id,
CASE relation_gen.family_seq
WHEN 1 THEN '配偶'
WHEN 2 THEN '父亲'
ELSE '母亲'
END AS relation_type,
CONCAT(
CASE MOD(relation_gen.staff_id + relation_gen.family_seq, 12)
WHEN 0 THEN ''
WHEN 1 THEN ''
WHEN 2 THEN ''
WHEN 3 THEN ''
WHEN 4 THEN ''
WHEN 5 THEN ''
WHEN 6 THEN ''
WHEN 7 THEN ''
WHEN 8 THEN ''
WHEN 9 THEN ''
WHEN 10 THEN ''
ELSE ''
END,
CASE MOD(relation_gen.staff_id * 3 + relation_gen.family_seq, 12)
WHEN 0 THEN ''
WHEN 1 THEN ''
WHEN 2 THEN ''
WHEN 3 THEN ''
WHEN 4 THEN ''
WHEN 5 THEN ''
WHEN 6 THEN ''
WHEN 7 THEN ''
WHEN 8 THEN ''
WHEN 9 THEN ''
WHEN 10 THEN ''
ELSE ''
END,
CASE MOD(relation_gen.staff_id * 7 + relation_gen.family_seq, 12)
WHEN 0 THEN ''
WHEN 1 THEN ''
WHEN 2 THEN ''
WHEN 3 THEN ''
WHEN 4 THEN ''
WHEN 5 THEN ''
WHEN 6 THEN ''
WHEN 7 THEN ''
WHEN 8 THEN ''
WHEN 9 THEN ''
WHEN 10 THEN ''
ELSE ''
END
) AS relation_name,
CASE relation_gen.family_seq
WHEN 1 THEN CASE MOD(relation_gen.staff_id, 2) WHEN 0 THEN 'F' ELSE 'M' END
WHEN 2 THEN 'M'
ELSE 'F'
END AS gender,
CASE relation_gen.family_seq
WHEN 1 THEN DATE_ADD('1982-01-01', INTERVAL MOD(relation_gen.staff_id * 17 + relation_gen.family_seq, 7000) DAY)
WHEN 2 THEN DATE_ADD('1957-01-01', INTERVAL MOD(relation_gen.staff_id * 11 + relation_gen.family_seq, 8000) DAY)
ELSE DATE_ADD('1960-01-01', INTERVAL MOD(relation_gen.staff_id * 13 + relation_gen.family_seq, 8000) DAY)
END AS birth_date,
'居民身份证' AS relation_cert_type,
CONCAT(
'320101',
DATE_FORMAT(
DATE_ADD('1970-01-01', INTERVAL MOD(relation_gen.staff_id * (relation_gen.family_seq + 7), 15000) DAY),
'%Y%m%d'
),
LPAD(MOD(relation_gen.staff_id * 10 + relation_gen.family_seq, 10000), 4, '0')
) AS relation_cert_no,
CONCAT(
'13',
LPAD(MOD(relation_gen.staff_id * 97 + relation_gen.family_seq * 13, 1000000000), 9, '0')
) AS mobile_phone1,
NULL AS mobile_phone2,
CASE relation_gen.family_seq
WHEN 1 THEN ROUND(80000 + MOD(relation_gen.staff_id, 8) * 12000, 2)
WHEN 2 THEN ROUND(50000 + MOD(relation_gen.staff_id, 7) * 7000, 2)
ELSE ROUND(45000 + MOD(relation_gen.staff_id, 7) * 6500, 2)
END AS annual_income,
NULL AS wechat_no1,
NULL AS wechat_no2,
NULL AS wechat_no3,
CONCAT('员工', relation_gen.staff_name, '家庭住址') AS contact_address,
CONCAT('2026-03-19补数脚本生成的', CASE relation_gen.family_seq WHEN 1 THEN '配偶' WHEN 2 THEN '父亲' ELSE '母亲' END) AS relation_desc,
NOW() AS effective_date,
NULL AS invalid_date,
1 AS status,
'2026-03-19补数脚本生成' AS remark,
'SYSTEM' AS data_source,
1 AS is_emp_family,
0 AS is_cust_family,
'system' AS created_by,
NOW() AS create_time,
'system' AS updated_by,
NOW() AS update_time
FROM (
SELECT
s.staff_id,
s.name AS staff_name,
s.id_card AS person_id,
IFNULL(p.preserved_count, 0) + seq.rel_seq AS family_seq
FROM ccdi_base_staff s
LEFT JOIN tmp_staff_family_preserved_count p
ON p.person_id = s.id_card
JOIN (
SELECT 1 AS rel_seq
UNION ALL
SELECT 2 AS rel_seq
UNION ALL
SELECT 3 AS rel_seq
) seq
ON seq.rel_seq <= GREATEST(MOD(s.staff_id, 3) + 1 - IFNULL(p.preserved_count, 0), 0)
) relation_gen;
-- 4. 补齐保留亲属的收入,并统一有效状态
UPDATE ccdi_staff_fmy_relation
SET annual_income = COALESCE(
annual_income,
ROUND(
CASE relation_type
WHEN '配偶' THEN 80000 + MOD(CRC32(CONCAT(person_id, '-', relation_cert_no)), 10) * 6000
WHEN '父亲' THEN 50000 + MOD(CRC32(CONCAT(person_id, '-', relation_cert_no)), 8) * 4000
WHEN '母亲' THEN 45000 + MOD(CRC32(CONCAT(person_id, '-', relation_cert_no)), 8) * 3500
ELSE 60000 + MOD(CRC32(CONCAT(person_id, '-', relation_cert_no)), 10) * 5000
END,
2
)
),
status = 1,
invalid_date = NULL,
data_source = COALESCE(NULLIF(data_source, ''), 'SYSTEM'),
is_emp_family = 1,
is_cust_family = 0,
updated_by = 'system',
update_time = NOW()
WHERE is_emp_family = 1;
COMMIT;
SELECT
COUNT(*) AS staff_count,
SUM(CASE WHEN annual_income IS NULL THEN 1 ELSE 0 END) AS income_null_count
FROM ccdi_base_staff;
SELECT
rel_cnt,
COUNT(*) AS staff_num
FROM (
SELECT
s.staff_id,
COUNT(r.id) AS rel_cnt
FROM ccdi_base_staff s
LEFT JOIN ccdi_staff_fmy_relation r
ON r.person_id = s.id_card
AND r.is_emp_family = 1
GROUP BY s.staff_id
) relation_summary
GROUP BY rel_cnt
ORDER BY rel_cnt;