feat(spec58): 4 张业务表 college_id 一次性回填脚本
以学生档案 gxmu_student.college_id 为准,按 user_id 回填 sjqn / tzbcy_form / qmgc_form / wxxzx_project 的 college_id;仍为空的行再用表单里的学院文本 按组织名 LIKE 兜底,只有唯一命中才写入,无法匹配留空。 - A 段学生档案主路径,优先取在校记录的学院,档案学院不唯一时留空不猜 - B 段文本兜底,候选学院 = 有平台单位号的节点 ∪ 学生档案引用过的节点 - 只填空不覆盖,可重复执行;不接定时任务 - 附回填率、空值清单、未匹配文本一览与一致性抽查(3a-3d),供人工核对
This commit is contained in:
@@ -0,0 +1,407 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- spec #58 / T6(issue #64):4 张在跑业务表的 college_id 一次性回填
|
||||||
|
--
|
||||||
|
-- 做什么:把「申报记录 → 申报人所在学院」写进 college_id。学院标识与
|
||||||
|
-- gxmu_student.college_id 是同一套 ID,都指向 sys_organization.organization_id
|
||||||
|
-- (见 docs/research/sso-org-data.md:24、ADR 0006「学院标识」)。
|
||||||
|
--
|
||||||
|
-- 执行顺序(不可打乱):
|
||||||
|
-- 1) 先执行 sql/20261110_spec58_approval_chain.sql(#59),它负责加 4 个 college_id 列。
|
||||||
|
-- 2) 整文件执行一次本脚本(mysql < 本文件)。文件内的段落顺序即执行顺序:
|
||||||
|
-- 0) 前置检查(只读) —— 先确认列在、名册有学院数据,否则后面的回填全是空转
|
||||||
|
-- 1) A 段 学生档案主路径 —— 申报记录 user_id → gxmu_student.college_id
|
||||||
|
-- 2) B 段 表单文本兜底 —— A 段后仍为空的行,用表单里的学院文本按组织名 LIKE 匹配
|
||||||
|
-- 3) 校验与清单(只读) —— 回填率、空值清单、未匹配文本一览,抄进上线记录
|
||||||
|
-- 3) ⚠ 只执行一次,不接定时任务。
|
||||||
|
--
|
||||||
|
-- 可重复执行:所有 UPDATE 都带「只填空、不覆盖」条件(college_id IS NULL),且不带会话状态
|
||||||
|
-- (不用临时表、不用视图),任何一句都可以单独重跑。重跑不会改掉人工修对的值。
|
||||||
|
--
|
||||||
|
-- 回滚:
|
||||||
|
-- #59 加列时 4 个 college_id 都是 NULL,本脚本只把 NULL 填成值,所以回滚就是把它们放回 NULL。
|
||||||
|
-- 执行前若已有人工填过的值,先自行快照(示例,取消注释后单独执行):
|
||||||
|
-- -- CREATE TABLE bak_20261110_college_id (module VARCHAR(64), rid BIGINT UNSIGNED, college_id INT, PRIMARY KEY (module, rid));
|
||||||
|
-- -- INSERT INTO bak_20261110_college_id SELECT 'gxmu_sjqn', id, college_id FROM gxmu_sjqn WHERE college_id IS NOT NULL;
|
||||||
|
-- (另 3 张表同形,module 换表名即可。)
|
||||||
|
-- 回滚语句见文件末尾「回滚」段,默认注释掉,避免整文件执行时误清空。
|
||||||
|
--
|
||||||
|
-- 口径(写清楚,避免二次解释):
|
||||||
|
-- * 「学院」以学生档案 gxmu_student.college_id 为准,它存的是 sys_organization.organization_id,
|
||||||
|
-- 与 gxmu_college.id 不是一套(缺口 G1,见调研文档)。本脚本不碰 gxmu_college。
|
||||||
|
-- * 学生档案优先取 status = 1(在校)那条的学院;同一 user_id 下学院不唯一时留空、不猜。
|
||||||
|
-- * 文本兜底只在「文本里恰好出现一个候选学院组织名」时写入;命中 0 个或多个都留空进清单。
|
||||||
|
-- * 候选学院节点 = 有平台单位号的节点(organization_code 非空,即开放平台同步的院系)
|
||||||
|
-- ∪ 学生档案实际引用过的节点。这样既不会把「药学院党委」这类手工节点当学院,
|
||||||
|
-- 也不用把学校根节点 ID 硬编码进脚本。
|
||||||
|
-- * 只处理 deleted = 0 的行;软删记录不参与回填,也不进回填率分母。
|
||||||
|
-- * 只按 user_id 关联学生(sys_user.user_id 全局唯一),tenant_id 不参与匹配。
|
||||||
|
-- * 不做学院层级推导、不建缺失的组织节点;匹配不上就是留空进清单。
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 0) 前置检查(只读)
|
||||||
|
-- college_id_columns 期望 4;students_with_college 期望 > 0(为 0 说明名册还没同步,先别跑回填)。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
SELECT COUNT(*) AS college_id_columns
|
||||||
|
FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME IN ('gxmu_sjqn', 'gxmu_tzbcy_form', 'gxmu_qmgc_form', 'gxmu_wxxzx_project')
|
||||||
|
AND COLUMN_NAME = 'college_id';
|
||||||
|
|
||||||
|
SELECT COUNT(*) AS students_with_college
|
||||||
|
FROM gxmu_student
|
||||||
|
WHERE deleted = 0 AND college_id IS NOT NULL;
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 1) A 段:学生档案主路径(以 gxmu_student.college_id 为准)
|
||||||
|
-- 同一个人(user_id)在名册里可能有多条:本科毕业的旧行 + 在读研究生行。
|
||||||
|
-- 取法:该 user_id 下学院唯一 → 直接用它;学院不唯一但「在校(status = 1)的学院」唯一
|
||||||
|
-- → 用在校那条的学院(同一个人的本科学院与研究生学院不同时,以在修为准)。
|
||||||
|
-- 两者都不满足 → 留空,不猜,交给 B 段文本或人工。
|
||||||
|
-- 只填空:WHERE t.college_id IS NULL;软删行与无申报人的行不处理。
|
||||||
|
-- no-op 说明:子查询无匹配行时 CASE 返回 NULL,等于把 NULL 再写一遍,不会破坏任何值。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UPDATE gxmu_sjqn t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE
|
||||||
|
WHEN COUNT(DISTINCT s.college_id) = 1 THEN MIN(s.college_id)
|
||||||
|
WHEN COUNT(DISTINCT CASE WHEN s.status = 1 THEN s.college_id END) = 1
|
||||||
|
THEN MIN(CASE WHEN s.status = 1 THEN s.college_id END)
|
||||||
|
END
|
||||||
|
FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0 AND t.user_id IS NOT NULL;
|
||||||
|
|
||||||
|
UPDATE gxmu_tzbcy_form t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE
|
||||||
|
WHEN COUNT(DISTINCT s.college_id) = 1 THEN MIN(s.college_id)
|
||||||
|
WHEN COUNT(DISTINCT CASE WHEN s.status = 1 THEN s.college_id END) = 1
|
||||||
|
THEN MIN(CASE WHEN s.status = 1 THEN s.college_id END)
|
||||||
|
END
|
||||||
|
FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0 AND t.user_id IS NOT NULL;
|
||||||
|
|
||||||
|
UPDATE gxmu_qmgc_form t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE
|
||||||
|
WHEN COUNT(DISTINCT s.college_id) = 1 THEN MIN(s.college_id)
|
||||||
|
WHEN COUNT(DISTINCT CASE WHEN s.status = 1 THEN s.college_id END) = 1
|
||||||
|
THEN MIN(CASE WHEN s.status = 1 THEN s.college_id END)
|
||||||
|
END
|
||||||
|
FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0 AND t.user_id IS NOT NULL;
|
||||||
|
|
||||||
|
UPDATE gxmu_wxxzx_project t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE
|
||||||
|
WHEN COUNT(DISTINCT s.college_id) = 1 THEN MIN(s.college_id)
|
||||||
|
WHEN COUNT(DISTINCT CASE WHEN s.status = 1 THEN s.college_id END) = 1
|
||||||
|
THEN MIN(CASE WHEN s.status = 1 THEN s.college_id END)
|
||||||
|
END
|
||||||
|
FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0 AND t.user_id IS NOT NULL;
|
||||||
|
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 2) B 段:表单文本兜底(A 段后仍为空的行)
|
||||||
|
-- 每张表的学院列名不同,逐个写(见 issue #64):
|
||||||
|
-- gxmu_sjqn.unit_name / gxmu_tzbcy_form.school_name /
|
||||||
|
-- gxmu_qmgc_form.school_info / gxmu_wxxzx_project.college_grade_class
|
||||||
|
-- 匹配方式:文本里包含某个候选学院的完整组织名(LIKE '%组织名%')。
|
||||||
|
-- 只有「恰好命中 1 个候选学院」才写入;命中 0 个或多个一律留空,进 3b/3c 的清单。
|
||||||
|
-- 候选学院节点 = 有平台单位号(organization_code 非空,开放平台同步的院系)
|
||||||
|
-- ∪ 学生档案实际引用过的组织节点。
|
||||||
|
-- 这样排除「药学院党委」「护理学院团委」这类手工节点,
|
||||||
|
-- 也不用把学校根节点 ID(24)硬编码进脚本。
|
||||||
|
-- 组织名为空的节点先排除:空名会成为 LIKE '%%' 匹配一切,把每行都变成「多义」。
|
||||||
|
-- 已知误配风险(文本包含关系,故意不猜):见 DONE 的 notes。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- gxmu_sjqn.unit_name(所在单位)
|
||||||
|
UPDATE gxmu_sjqn t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE WHEN COUNT(*) = 1 THEN MIN(o.organization_id) END
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND t.unit_name LIKE CONCAT('%', o.organization_name, '%')
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0
|
||||||
|
AND t.unit_name IS NOT NULL AND t.unit_name <> '';
|
||||||
|
|
||||||
|
-- gxmu_tzbcy_form.school_name(学校名称)
|
||||||
|
UPDATE gxmu_tzbcy_form t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE WHEN COUNT(*) = 1 THEN MIN(o.organization_id) END
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND t.school_name LIKE CONCAT('%', o.organization_name, '%')
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0
|
||||||
|
AND t.school_name IS NOT NULL AND t.school_name <> '';
|
||||||
|
|
||||||
|
-- gxmu_qmgc_form.school_info(学校、院系、年级、专业)
|
||||||
|
UPDATE gxmu_qmgc_form t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE WHEN COUNT(*) = 1 THEN MIN(o.organization_id) END
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND t.school_info LIKE CONCAT('%', o.organization_name, '%')
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0
|
||||||
|
AND t.school_info IS NOT NULL AND t.school_info <> '';
|
||||||
|
|
||||||
|
-- gxmu_wxxzx_project.college_grade_class(学院、年级、班别)
|
||||||
|
UPDATE gxmu_wxxzx_project t
|
||||||
|
SET college_id = (
|
||||||
|
SELECT CASE WHEN COUNT(*) = 1 THEN MIN(o.organization_id) END
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND t.college_grade_class LIKE CONCAT('%', o.organization_name, '%')
|
||||||
|
)
|
||||||
|
WHERE t.college_id IS NULL AND t.deleted = 0
|
||||||
|
AND t.college_grade_class IS NOT NULL AND t.college_grade_class <> '';
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 3a) 回填率(只读):每张表一行
|
||||||
|
-- total_rows 参与统计的行数(deleted = 0)
|
||||||
|
-- filled_rows 有学院标识的行数
|
||||||
|
-- null_rows 仍为空的行数,等于「3b 空值清单」里该 module 的行数
|
||||||
|
-- fill_rate_pct 回填率;total_rows = 0 时为 NULL(空表没有回填率)
|
||||||
|
-- 期望:4 行;total_rows = filled_rows + null_rows
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
SELECT 'gxmu_sjqn' AS module, COUNT(*) AS total_rows,
|
||||||
|
SUM(college_id IS NOT NULL) AS filled_rows,
|
||||||
|
SUM(college_id IS NULL) AS null_rows,
|
||||||
|
ROUND(SUM(college_id IS NOT NULL) / NULLIF(COUNT(*), 0) * 100, 1) AS fill_rate_pct
|
||||||
|
FROM gxmu_sjqn WHERE deleted = 0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_tzbcy_form', COUNT(*), SUM(college_id IS NOT NULL), SUM(college_id IS NULL),
|
||||||
|
ROUND(SUM(college_id IS NOT NULL) / NULLIF(COUNT(*), 0) * 100, 1)
|
||||||
|
FROM gxmu_tzbcy_form WHERE deleted = 0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_qmgc_form', COUNT(*), SUM(college_id IS NOT NULL), SUM(college_id IS NULL),
|
||||||
|
ROUND(SUM(college_id IS NOT NULL) / NULLIF(COUNT(*), 0) * 100, 1)
|
||||||
|
FROM gxmu_qmgc_form WHERE deleted = 0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_wxxzx_project', COUNT(*), SUM(college_id IS NOT NULL), SUM(college_id IS NULL),
|
||||||
|
ROUND(SUM(college_id IS NOT NULL) / NULLIF(COUNT(*), 0) * 100, 1)
|
||||||
|
FROM gxmu_wxxzx_project WHERE deleted = 0;
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 3b) 空值清单(只读):本次没能回填上学院的行,逐行列出供人工核对
|
||||||
|
-- 输出列:
|
||||||
|
-- module 哪张表
|
||||||
|
-- id 申报记录主键(回填时直接 UPDATE ... WHERE id = ?)
|
||||||
|
-- user_id 申报人账号;为空说明这条记录没绑定登录人,两条路径都走不通
|
||||||
|
-- college_text 表单里填的学院文本(sjqn.unit_name / tzbcy_form.school_name /
|
||||||
|
-- qmgc_form.school_info / wxxzx_project.college_grade_class)
|
||||||
|
-- student_college 学生档案解析出的学院名与 ID,多个用 / 分隔;
|
||||||
|
-- 为空 = 名册里没这个人或学院没解析出来,多个 = 档案里学院不唯一
|
||||||
|
-- reason 粗分原因,便于分组处理(明细仍看 student_college 与 3c)
|
||||||
|
-- 期望:4 张表的空值行都出现在这里;填完之后可按 reason 分组人工处理。
|
||||||
|
-- ⚠ 人工处理后重跑本文件即可(只填空不覆盖),不需要删数据。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
SELECT 'gxmu_sjqn' AS module, t.id, t.user_id, t.unit_name AS college_text,
|
||||||
|
(SELECT GROUP_CONCAT(DISTINCT CONCAT(o.organization_name, '(', o.organization_id, ')') SEPARATOR ' / ')
|
||||||
|
FROM gxmu_student s JOIN sys_organization o ON o.organization_id = s.college_id
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id) AS student_college,
|
||||||
|
CASE
|
||||||
|
WHEN t.user_id IS NULL THEN '无申报人'
|
||||||
|
WHEN NOT EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL)
|
||||||
|
THEN '学生档案无学院'
|
||||||
|
WHEN (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) > 1
|
||||||
|
THEN '学生档案学院不唯一'
|
||||||
|
WHEN t.unit_name IS NULL OR t.unit_name = '' THEN '表单未填学院文本'
|
||||||
|
ELSE '文本未唯一匹配(见 3c)'
|
||||||
|
END AS reason
|
||||||
|
FROM gxmu_sjqn t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_tzbcy_form', t.id, t.user_id, t.school_name,
|
||||||
|
(SELECT GROUP_CONCAT(DISTINCT CONCAT(o.organization_name, '(', o.organization_id, ')') SEPARATOR ' / ')
|
||||||
|
FROM gxmu_student s JOIN sys_organization o ON o.organization_id = s.college_id
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id),
|
||||||
|
CASE
|
||||||
|
WHEN t.user_id IS NULL THEN '无申报人'
|
||||||
|
WHEN NOT EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL)
|
||||||
|
THEN '学生档案无学院'
|
||||||
|
WHEN (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) > 1
|
||||||
|
THEN '学生档案学院不唯一'
|
||||||
|
WHEN t.school_name IS NULL OR t.school_name = '' THEN '表单未填学院文本'
|
||||||
|
ELSE '文本未唯一匹配(见 3c)'
|
||||||
|
END
|
||||||
|
FROM gxmu_tzbcy_form t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_qmgc_form', t.id, t.user_id, t.school_info,
|
||||||
|
(SELECT GROUP_CONCAT(DISTINCT CONCAT(o.organization_name, '(', o.organization_id, ')') SEPARATOR ' / ')
|
||||||
|
FROM gxmu_student s JOIN sys_organization o ON o.organization_id = s.college_id
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id),
|
||||||
|
CASE
|
||||||
|
WHEN t.user_id IS NULL THEN '无申报人'
|
||||||
|
WHEN NOT EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL)
|
||||||
|
THEN '学生档案无学院'
|
||||||
|
WHEN (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) > 1
|
||||||
|
THEN '学生档案学院不唯一'
|
||||||
|
WHEN t.school_info IS NULL OR t.school_info = '' THEN '表单未填学院文本'
|
||||||
|
ELSE '文本未唯一匹配(见 3c)'
|
||||||
|
END
|
||||||
|
FROM gxmu_qmgc_form t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_wxxzx_project', t.id, t.user_id, t.college_grade_class,
|
||||||
|
(SELECT GROUP_CONCAT(DISTINCT CONCAT(o.organization_name, '(', o.organization_id, ')') SEPARATOR ' / ')
|
||||||
|
FROM gxmu_student s JOIN sys_organization o ON o.organization_id = s.college_id
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id),
|
||||||
|
CASE
|
||||||
|
WHEN t.user_id IS NULL THEN '无申报人'
|
||||||
|
WHEN NOT EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL)
|
||||||
|
THEN '学生档案无学院'
|
||||||
|
WHEN (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) > 1
|
||||||
|
THEN '学生档案学院不唯一'
|
||||||
|
WHEN t.college_grade_class IS NULL OR t.college_grade_class = '' THEN '表单未填学院文本'
|
||||||
|
ELSE '文本未唯一匹配(见 3c)'
|
||||||
|
END
|
||||||
|
FROM gxmu_wxxzx_project t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL;
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 3c) 未匹配文本一览(只读):把空值清单里的学院文本去重,看它到底命中了哪些组织名
|
||||||
|
-- matched_names 为空 = 文本里没有任何候选学院名(填错了 / 写的是简称 / 不是学院);
|
||||||
|
-- 出现 2 个以上 = 组织树里有同义节点(如「生命科学与医学工程学院」与「生命科学与医学工程」),
|
||||||
|
-- 这种按「宁可留空」的口径留给人工判断,不自动挑一个。
|
||||||
|
-- row_count 是该文本下仍未回填的行数。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
SELECT 'gxmu_sjqn' AS module, v.college_text, v.row_count,
|
||||||
|
(SELECT GROUP_CONCAT(o.organization_name ORDER BY o.organization_name SEPARATOR ' / ')
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND v.college_text LIKE CONCAT('%', o.organization_name, '%')) AS matched_names
|
||||||
|
FROM (SELECT unit_name AS college_text, COUNT(*) AS row_count
|
||||||
|
FROM gxmu_sjqn WHERE deleted = 0 AND college_id IS NULL
|
||||||
|
GROUP BY unit_name) v
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_tzbcy_form', v.college_text, v.row_count,
|
||||||
|
(SELECT GROUP_CONCAT(o.organization_name ORDER BY o.organization_name SEPARATOR ' / ')
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND v.college_text LIKE CONCAT('%', o.organization_name, '%'))
|
||||||
|
FROM (SELECT school_name AS college_text, COUNT(*) AS row_count
|
||||||
|
FROM gxmu_tzbcy_form WHERE deleted = 0 AND college_id IS NULL
|
||||||
|
GROUP BY school_name) v
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_qmgc_form', v.college_text, v.row_count,
|
||||||
|
(SELECT GROUP_CONCAT(o.organization_name ORDER BY o.organization_name SEPARATOR ' / ')
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND v.college_text LIKE CONCAT('%', o.organization_name, '%'))
|
||||||
|
FROM (SELECT school_info AS college_text, COUNT(*) AS row_count
|
||||||
|
FROM gxmu_qmgc_form WHERE deleted = 0 AND college_id IS NULL
|
||||||
|
GROUP BY school_info) v
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_wxxzx_project', v.college_text, v.row_count,
|
||||||
|
(SELECT GROUP_CONCAT(o.organization_name ORDER BY o.organization_name SEPARATOR ' / ')
|
||||||
|
FROM sys_organization o
|
||||||
|
WHERE o.deleted = 0
|
||||||
|
AND o.organization_name <> ''
|
||||||
|
AND ( (o.organization_code IS NOT NULL AND o.organization_code <> '')
|
||||||
|
OR EXISTS (SELECT 1 FROM gxmu_student s WHERE s.deleted = 0 AND s.college_id = o.organization_id) )
|
||||||
|
AND v.college_text LIKE CONCAT('%', o.organization_name, '%'))
|
||||||
|
FROM (SELECT college_grade_class AS college_text, COUNT(*) AS row_count
|
||||||
|
FROM gxmu_wxxzx_project WHERE deleted = 0 AND college_id IS NULL
|
||||||
|
GROUP BY college_grade_class) v;
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 3d) 一致性抽查(只读)
|
||||||
|
-- a/b 段期望返回空集:回填出的学院 ID 在组织表里不存在(历史脏数据 / 节点被删)或节点已软删。
|
||||||
|
-- c 段期望每张表都是 0:有 user_id 且学生档案学院唯一、却仍为空的行;
|
||||||
|
-- 非 0 说明 A 段没执行或执行顺序被打乱。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
SELECT 'gxmu_sjqn' AS module, t.id, t.college_id
|
||||||
|
FROM gxmu_sjqn t
|
||||||
|
LEFT JOIN sys_organization o ON o.organization_id = t.college_id
|
||||||
|
WHERE t.college_id IS NOT NULL AND (o.organization_id IS NULL OR o.deleted = 1)
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_tzbcy_form', t.id, t.college_id
|
||||||
|
FROM gxmu_tzbcy_form t
|
||||||
|
LEFT JOIN sys_organization o ON o.organization_id = t.college_id
|
||||||
|
WHERE t.college_id IS NOT NULL AND (o.organization_id IS NULL OR o.deleted = 1)
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_qmgc_form', t.id, t.college_id
|
||||||
|
FROM gxmu_qmgc_form t
|
||||||
|
LEFT JOIN sys_organization o ON o.organization_id = t.college_id
|
||||||
|
WHERE t.college_id IS NOT NULL AND (o.organization_id IS NULL OR o.deleted = 1)
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_wxxzx_project', t.id, t.college_id
|
||||||
|
FROM gxmu_wxxzx_project t
|
||||||
|
LEFT JOIN sys_organization o ON o.organization_id = t.college_id
|
||||||
|
WHERE t.college_id IS NOT NULL AND (o.organization_id IS NULL OR o.deleted = 1);
|
||||||
|
|
||||||
|
-- c) 应为 0 行
|
||||||
|
SELECT 'gxmu_sjqn' AS module, COUNT(*) AS unexpected_null
|
||||||
|
FROM gxmu_sjqn t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL AND t.user_id IS NOT NULL
|
||||||
|
AND (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) = 1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_tzbcy_form', COUNT(*)
|
||||||
|
FROM gxmu_tzbcy_form t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL AND t.user_id IS NOT NULL
|
||||||
|
AND (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) = 1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_qmgc_form', COUNT(*)
|
||||||
|
FROM gxmu_qmgc_form t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL AND t.user_id IS NOT NULL
|
||||||
|
AND (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) = 1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'gxmu_wxxzx_project', COUNT(*)
|
||||||
|
FROM gxmu_wxxzx_project t
|
||||||
|
WHERE t.deleted = 0 AND t.college_id IS NULL AND t.user_id IS NOT NULL
|
||||||
|
AND (SELECT COUNT(DISTINCT s.college_id) FROM gxmu_student s
|
||||||
|
WHERE s.deleted = 0 AND s.user_id = t.user_id AND s.college_id IS NOT NULL) = 1;
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- 回滚(需要时才执行;默认注释,避免整文件执行时把值清空)
|
||||||
|
-- 只清本脚本可能写过的行:把这 4 张表的 college_id 全部置回 NULL。
|
||||||
|
-- 人工修过的值也会一起清掉,所以先按文件头「快照」段留备份。
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- UPDATE gxmu_sjqn SET college_id = NULL WHERE college_id IS NOT NULL;
|
||||||
|
-- UPDATE gxmu_tzbcy_form SET college_id = NULL WHERE college_id IS NOT NULL;
|
||||||
|
-- UPDATE gxmu_qmgc_form SET college_id = NULL WHERE college_id IS NOT NULL;
|
||||||
|
-- UPDATE gxmu_wxxzx_project SET college_id = NULL WHERE college_id IS NOT NULL;
|
||||||
Reference in New Issue
Block a user