package main /* 思路: 按照三个SQL进行查询,结果封装到指定结构体,并对比三个查询结果,按照姓名和身份证作为关联项,任意其他项值不等,则保留下来 */ import ( "database/sql" "fmt" excelize "github.com/xuri/excelize/v2" "strings" "time" _ "github.com/go-sql-driver/mysql" ) var SQLJck = ` select ifnull(A0184,'')IDNumber, ifnull(A0101,'') Name, ifnull(substr(a0107, 1, 6),'') BirthDate, IF(A0104 = 1, '男', '女') Gender, ifnull((select min(code_name) from code_value where A0117=code_value and code_type='GB3304'),'') Ethnicity, ifnull(substr(a0134, 1, 6),'') WorkStartDate, ifnull((select min(code_name) from code_value where A0141=code_value and code_type='GB4762'),'') PoliticalStatus, ifnull((select case when A0801B like '1%' then '研究生' when A0801B like '2%' then '大学本科' when A0801B like '3%' then '大学专科' else '中专及以下' end from A08 where A0831=1 and A01.A0000=A08.A0000), '') FullTimeEducation, ifnull((select case when A0801B like '1%' then '研究生' when A0801B like '2%' then '大学本科' when A0801B like '3%' then '大学专科' else '中专及以下' end from A08 where A0834=1 and A01.A0000=A08.A0000), '') HighestEducation, ifnull((select case when A0831 like '3%' then '硕士' when A0831 like '4%' then '学士' else '博士' end from A08 where A0835=1 and A01.A0000=A08.A0000), '') HighestDegree, ifnull((select min(code_name) from code_value where A0123=code_value and code_type='XZ93'),'') JobCategory, ifnull((select min(code_name) from A05, code_value where A0501B=code_value and code_type='ZB09' and A0531=0 and A0524=1 and A01.A0000=A05.A0000), '') CurrentPositionLevel, ifnull((select substr(A0504, 1, 6) from A05 where A0531=0 and A0524=1 and A01.A0000=A05.A0000), '') CurrentPositionStartDate, ifnull((select min(code_name) from A05, code_value where A0501B=code_value and code_type='ZB148' and A0531=1 and A0524=1 and A01.A0000=A05.A0000), '') CurrentRankLevel, (select ifnull(DATE_FORMAT(DATE_ADD(concat(substr(A0530, 1, 4),'-',substr(A0530, 5, 2),'-01'), INTERVAL ifnull(A0532, 0) MONTH), '%Y%m'), substr(A0504, 1, 6)) from A05 where A0531=1 and A0524=1 and A01.A0000=A05.A0000) CurrentRankStartDate, IF(A0197 = 1, '是', '否') Has2YearsGrassrootsExp, ifnull((select min(code_name) from A15, code_value where A1517=code_value and code_type='ZB18' and A1521='2023' and A01.A0000=A15.A0000), '') AnnualAssessment2023, ifnull((select min(code_name) from code_value where A0160=code_value and code_type='ZB125'),'') PersonCategory, ifnull((select '是' from A99Z1 where A99Z101=1 and A99Z103=1 and A99Z102 like '2024%' and A01.A0000=A99Z1.A0000), '否') SelectedFor2024 from A01 where A0163 = '1' ` var SQLZjk = ` select ifnull(M0203,'') IDNumber, ifnull(M0201,'') Name, ifnull(substr(M0204, 1, 6) ,'') BirthDate, IF(M0202 = 1, '男', '女') Gender, ifnull((select min(code_name) from code_value where M0205=code_value and code_type='M_D_CM16'),'') Ethnicity, ifnull(substr(M0216, 1, 6),'') WorkStartDate, ifnull((select min(code_name) from code_value where M0206=code_value and code_type='M_D_CD17'),'') PoliticalStatus, ifnull((select min(code_name) from code_value where M0242=code_value and code_type='M_D_C11'),'') FullTimeEducation, ifnull((select min(code_name) from code_value where M0212=code_value and code_type='M_D_C11'),'') HighestEducation, ifnull((select min(code_name) from code_value where M0213=code_value and code_type='M_D_C12'),'') HighestDegree, ifnull((select min(code_name) from code_value where M0246=code_value and code_type='M_D_M0246_1'),'') JobCategory, ifnull((select min(code_name) from code_value where M0208=code_value and code_type='M_D_C32_2019'),'') CurrentPositionLevel, ifnull(substr(M0233, 1, 6),'') CurrentPositionStartDate, ifnull((select min(code_name) from code_value where M0243=code_value and code_type='M_D_C31_2019'),'') CurrentRankLevel, ifnull(substr(M0244, 1, 6),'') CurrentRankStartDate, IF(M0215 = 1, '是', '否') Has2YearsGrassrootsExp, ifnull((select min(code_name) from M_M09, code_value where M0905=code_value and code_type='M_D_CM16' and M0902=M0203),'') AnnualAssessment2023, ifnull((select case M0104 when 2 then '参照管理机关工作人员' when 3 then '参照管理事业单位人员' else '公务员' end from M_M01 where M_M01.UNID=M_M02.UNID and rpt='2024' limit 1),'') PersonCategory, ifnull((select '是' from M_M05 where M0503=M0203 and rpt='2024' limit 1),'否') SelectedFor2024 from M_M02 where rpt = '2024' ` var SQLGzk = ` select ifnull(S0203,'') IDNumber, ifnull(S0201,'') Name, '-' BirthDate, '-' Gender, '-' Ethnicity, '-' WorkStartDate, '-' PoliticalStatus, '-' FullTimeEducation, ifnull((select min(code_name) from code_value where S0225=code_value and code_type='M_D_C11'),'') HighestEducation, '-' HighestDegree, '-' JobCategory, ifnull((select min(code_name) from code_value where S0204=code_value and code_type='M_D_S0204'),'') CurrentPositionLevel, '-' CurrentPositionStartDate, ifnull((select min(code_name) from code_value where S0205=code_value and code_type='ZB148'),'') CurrentRankLevel, '-' CurrentRankStartDate, '-' Has2YearsGrassrootsExp, '-' AnnualAssessment2023, '-' PersonCategory, '-' SelectedFor2024 from m_s02 where rpt='2024' union all select ifnull(S0403,'') IDNumber, ifnull(S0401,'') Name, '-' BirthDate, '-' Gender, '-' Ethnicity, '-' WorkStartDate, '-' PoliticalStatus, '-' FullTimeEducation, ifnull((select min(code_name) from code_value where S0425=code_value and code_type='M_D_C11'),'') HighestEducation, '-' HighestDegree, '-' JobCategory, ifnull((select min(code_name) from code_value where S0404=code_value and code_type='M_D_S0204'),'') CurrentPositionLevel, '-' CurrentPositionStartDate, ifnull((select min(code_name) from code_value where S0405=code_value and code_type='ZB148'),'') CurrentRankLevel, '-' CurrentRankStartDate, '-' Has2YearsGrassrootsExp, '-' AnnualAssessment2023, '-' PersonCategory, '-' SelectedFor2024 from m_s04 where rpt='2024' ` var SQLCzk = ` select A0101 Name, A0184 IDNumber, ifnull((select min(code_name) from code_value where A0221=code_value and code_type='ZB09'),'') CurrentPositionLevel, ifnull((select min(code_name) from code_value where A0192E=code_value and code_type='ZB148'),'') CurrentRankLevel, ifnull(A0195, '') OldWork from C01 where C0105 like '2024%' ` var SQLBhb = ` select M0501 Name, M0503 IDNumber, ifnull((select min(code_name) from code_value where M0515=code_value and code_type='ZB09'),'') CurrentPositionLevel, ifnull((select min(code_name) from code_value where M0515=code_value and code_type='ZB148'),'') CurrentRankLevel, M0510 OldWork from M_M05 a where M0511=2 and M0514=3 ` // 存在所有对象信息 - 集合 func main() { db, _ := sql.Open("mysql", "root:admin@tcp(127.0.0.1:35017)/hy_qggwy?charset=utf8") fmt.Println("操作数据库连接:", db) // 创建临时文件夹 dir := time.Now().Format("2006102150405") file := fmt.Sprintf("对比结果-%s.xlsx", dir) peoplesJck := queryBySQL(db, SQLJck) peoplesZjk := queryBySQL(db, SQLZjk) peoplesGzk := queryBySQL(db, SQLGzk) results1 := mergeResults(peoplesJck, peoplesZjk, peoplesGzk) peoplesCzk := queryByCzSQL(db, SQLCzk) peoplesBhb := queryByCzSQL(db, SQLBhb) results2 := mergeCzResults(peoplesCzk, peoplesBhb) // 创建一个新的 Excel 文件 f := excelize.NewFile() _ = f.NewSheet("三库对比") _ = f.NewSheet("辞职人员对比") saveSheet1(f, results1) saveSheet2(f, results2) f.DeleteSheet("Sheet1") f.SetActiveSheet(1) // 保存文件 if err := f.SaveAs(file); err != nil { fmt.Println("保存文件失败:", err) } else { fmt.Printf("文件已保存为 %s", file) } fmt.Println("执行结束!") } /* */ func saveSheet1(f *excelize.File, results []Diff) { sheetName := "三库对比" // 设置表头 headers := []string{"身份证号", "姓名", "项名称", "基础库", "中间库", "工资库"} for i, header := range headers { cell := fmt.Sprintf("%c1", 'A'+i) _ = f.SetCellValue(sheetName, cell, header) } // 写入数据 for i, diff := range results { row := i + 2 // 数据从第二行开始 _ = f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), diff.IDNumber) _ = f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), diff.Name) _ = f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), diff.ColName) _ = f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), diff.Jck) _ = f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), diff.Zjk) _ = f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), diff.Gzk) } } /* */ func saveSheet2(f *excelize.File, results []Diff) { sheetName := "辞职人员对比" // 设置表头 headers := []string{"身份证号", "姓名", "项名称", "辞职库", "中间库"} for i, header := range headers { cell := fmt.Sprintf("%c1", 'A'+i) _ = f.SetCellValue(sheetName, cell, header) } // 写入数据 for i, diff := range results { row := i + 2 // 数据从第二行开始 _ = f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), diff.IDNumber) _ = f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), diff.Name) _ = f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), diff.ColName) _ = f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), diff.Jck) _ = f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), diff.Zjk) } } /* queryBySQL 按照基础脚本查询 */ func queryBySQL(db *sql.DB, SQLJck string) []Person { rows, err := db.Query(SQLJck) if err != nil { _ = fmt.Errorf("发生报错:%s", err) } defer func(rows *sql.Rows) { err := rows.Close() if err != nil { fmt.Printf("错误") } }(rows) var people []Person for rows.Next() { var p Person err := rows.Scan( &p.IDNumber, &p.Name, &p.BirthDate, &p.Gender, &p.Ethnicity, &p.WorkStartDate, &p.PoliticalStatus, &p.FullTimeEducation, &p.HighestEducation, &p.HighestDegree, &p.JobCategory, &p.CurrentPositionLevel, &p.CurrentPositionStartDate, &p.CurrentRankLevel, &p.CurrentRankStartDate, &p.Has2YearsGrassrootsExp, &p.AnnualAssessment2023, &p.PersonCategory, &p.SelectedFor2024, ) if err != nil { _ = fmt.Errorf("发生报错:%s", err) } people = append(people, p) } if err = rows.Err(); err != nil { _ = fmt.Errorf("发生报错:%s", err) } return people } /* queryByCzSQL 按照辞职脚本查询 */ func queryByCzSQL(db *sql.DB, SQLCz string) []CzPerson { rows, err := db.Query(SQLCz) if err != nil { _ = fmt.Errorf("发生报错:%s", err) } defer func(rows *sql.Rows) { err := rows.Close() if err != nil { fmt.Printf("错误") } }(rows) var people []CzPerson for rows.Next() { var p CzPerson err := rows.Scan( &p.Name, &p.IDNumber, &p.CurrentPositionLevel, &p.CurrentRankLevel, &p.OldWork, ) if err != nil { _ = fmt.Errorf("发生报错:%s", err) } people = append(people, p) } if err = rows.Err(); err != nil { _ = fmt.Errorf("发生报错:%s", err) } return people } /* mergeResults 基础人员对比 */ func mergeResults(peoplesJck, peoplesZjk, peoplesGzk []Person) []Diff { jckMap := mapPersonToDiff(peoplesJck, "基础库") zjkMap := mapPersonToDiff(peoplesZjk, "中间库") gzkMap := mapPersonToDiff(peoplesGzk, "工资库") var diffs []Diff // 遍历所有可能的键 allKeys := make(map[string]bool) for key := range jckMap { allKeys[key] = true } for key := range zjkMap { allKeys[key] = true } for key := range gzkMap { allKeys[key] = true } for key := range allKeys { idNumber := strings.Split(key, "_")[0] name := strings.Split(key, "_")[1] // 获取每个属性的值 for colName := range jckMap[key] { if colName == "身份证号" || colName == "姓名" { continue } var diff Diff if gzMap[colName] { // 指定需要注意工资部分 if jckMap[key][colName] != zjkMap[key][colName] || jckMap[key][colName] != gzkMap[key][colName] || zjkMap[key][colName] != gzkMap[key][colName] { diff = Diff{ IDNumber: idNumber, Name: name, ColName: colName, Jck: jckMap[key][colName], Zjk: zjkMap[key][colName], Gzk: gzkMap[key][colName], } diffs = append(diffs, diff) } } else { // 需要公共比较 if jckMap[key][colName] != zjkMap[key][colName] { diff = Diff{ IDNumber: idNumber, Name: name, ColName: colName, Jck: jckMap[key][colName], Zjk: zjkMap[key][colName], Gzk: gzkMap[key][colName], } diffs = append(diffs, diff) } } } } return diffs } /* mergeCzResults 辞职人员对比 */ func mergeCzResults(peoplesCzk, peoplesBhb []CzPerson) []Diff { jckMap := mapCzPersonToDiff(peoplesCzk, "辞职库") zjkMap := mapCzPersonToDiff(peoplesBhb, "辞职表") var diffs []Diff // 遍历所有可能的键 allKeys := make(map[string]bool) for key := range jckMap { allKeys[key] = true } for key := range zjkMap { allKeys[key] = true } for key := range allKeys { idNumber := strings.Split(key, "_")[0] name := strings.Split(key, "_")[1] // 获取每个属性的值 for colName := range jckMap[key] { if colName == "身份证号" || colName == "姓名" { continue } var diff Diff // 需要公共比较 if colName == "职务层次" || colName == "职级" { if jckMap[key][colName] == zjkMap[key][colName] || jckMap[key]["职务层次"] == zjkMap[key]["职级"] || jckMap[key]["职级"] == zjkMap[key]["职务层次"] { continue } } if jckMap[key][colName] != zjkMap[key][colName] { diff = Diff{ IDNumber: idNumber, Name: name, ColName: colName, Jck: jckMap[key][colName], Zjk: zjkMap[key][colName], } diffs = append(diffs, diff) } } } return diffs } // 示例数组 var gzMap map[string]bool func init() { ArrGz := []string{"身份证号", "姓名", "最高学历", "现职务层次", "现职级层次"} // 将数组转换为 map gzMap = make(map[string]bool) for _, item := range ArrGz { gzMap[item] = true } } /* mapPersonToDiff 基础查询对比 */ func mapPersonToDiff(people []Person, source string) map[string]map[string]string { result := make(map[string]map[string]string) for _, person := range people { key := person.IDNumber + "_" + person.Name if result[key] == nil { result[key] = make(map[string]string) } result[key]["身份证号"] = person.IDNumber result[key]["姓名"] = person.Name result[key]["出生时间"] = person.BirthDate result[key]["性别"] = person.Gender result[key]["民族"] = person.Ethnicity result[key]["参加工作时间"] = person.WorkStartDate result[key]["政治面貌"] = person.PoliticalStatus result[key]["全日制学历"] = person.FullTimeEducation result[key]["最高学历"] = person.HighestEducation result[key]["最高学位"] = person.HighestDegree result[key]["职位类别"] = person.JobCategory result[key]["现职务层次"] = person.CurrentPositionLevel result[key]["任现职务层次时间"] = person.CurrentPositionStartDate result[key]["现职级层次"] = person.CurrentRankLevel result[key]["任现职级层次时间"] = person.CurrentRankStartDate result[key]["是否具有2年以上基层经验"] = person.Has2YearsGrassrootsExp result[key]["2023年度考核结果"] = person.AnnualAssessment2023 result[key]["人员类别"] = person.PersonCategory result[key]["2024年考录选调生"] = person.SelectedFor2024 } return result } /* mapCzPersonToDiff 辞职查询对比 */ func mapCzPersonToDiff(people []CzPerson, source string) map[string]map[string]string { result := make(map[string]map[string]string) for _, person := range people { key := person.IDNumber + "_" + person.Name if result[key] == nil { result[key] = make(map[string]string) } result[key]["身份证号"] = person.IDNumber result[key]["姓名"] = person.Name result[key]["职务层次"] = person.CurrentPositionLevel result[key]["职级"] = person.CurrentRankLevel result[key]["原职务"] = person.OldWork } return result } type Person struct { IDNumber string // 身份证号 Name string // 姓名 BirthDate string // 出生时间 Gender string // 性别 Ethnicity string // 民族 WorkStartDate string // 参加工作时间 PoliticalStatus string // 政治面貌 FullTimeEducation string // 全日制学历 HighestEducation string // 最高学历 HighestDegree string // 最高学位 JobCategory string // 职位类别 CurrentPositionLevel string // 现职务层次 CurrentPositionStartDate string // 任现职务层次时间 CurrentRankLevel string // 现职级层次 CurrentRankStartDate string // 任现职级层次时间 Has2YearsGrassrootsExp string // 是否具有2年以上基层经验 AnnualAssessment2023 string // 2023年度考核结果 PersonCategory string // 人员类别 SelectedFor2024 string // 2024年考录选调生 } type CzPerson struct { IDNumber string // 身份证号 Name string // 姓名 CurrentPositionLevel string // 职务层次 CurrentRankLevel string // 职级 OldWork string // 原职务 } type Diff struct { IDNumber string `json:"身份证号"` // 身份证号 Name string `json:"姓名"` // 姓名 ColName string `json:"项名称"` // 项名称 Jck string `json:"基础库"` // 基础库 Zjk string `json:"中间库"` // 中间库 Gzk string `json:"工资库"` // 工资库 }