本文编写于 324 天前,最后修改于 324 天前,其中某些信息可能已经过时。

任务背景:当Excel遇上复杂统计

女友深夜发来求救信息:"老师让我统计6个学科团队在8个不同奖项表中的获奖情况,每个奖项表还有8个sheet!" 作为一个🐕,我立刻意识到这是个典型的多源数据关联分析问题。虽然我不想做,我想出去跑顺风车,但是女友包了一个大红包,想想还是技术问题更加重要。

顺便回了礼物备注为iPhone 16 pro max

原始数据结构

团队表A(学科团队信息) | 序号 | 姓名 | 职务 | 团队 |

奖项表B1-B8(每个表含8个sheet) | 序号 | 姓名 | 奖项 | 其他备注 |

技术选型:为什么放弃Excel

VLOOKUP的致命缺陷

尝试用VLOOKUP后发现:

  • 姓名匹配问题:"张三" ≠ "张三丰" ≠ "张 三"
  • 无法处理"张三、李四共同获奖"的情况
  • 跨64个sheet(8文件×8sheet)操作简直是噩梦

FILTER函数的局限性

虽然能实现基础筛选:

=FILTER(获奖表!C:C, 获奖表!B:B=A2)

但批处理困难,手动操作64次后我的手指已经抗议了。

SQL解决方案全流程

1. 环境准备

祭出我的"老伙计"技术栈:

  • XAMPP(集成了MariaDB)
  • VS Code(写SQL和笔记)
  • Excel(初步查看数据)

2. 数据清洗实战

这是最耗时的环节,处理了:

  • 姓名中的空格:"张 三" → "张三"
  • 统一标点:将中文顿号"、"替换为逗号","
  • 去除职称:"李四(教授)" → "李四"
  • 处理跨行数据

最终将每个sheet另存为UTF-8编码的CSV文件。

3. 数据库设计

通过DeepSeek生成基础建表语句后,手动优化:

CREATE TABLE teams (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL COMMENT '清洗后的姓名',
    position VARCHAR(50),
    team VARCHAR(30) NOT NULL,
    INDEX idx_name (name(10))
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE awards (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    award VARCHAR(100),
    remark TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

特别注意事项:

  • utf8mb4编码支持所有Unicode字符
  • VARCHAR长度预留足够空间
  • 为姓名字段添加前缀索引

4. 数据导入

使用phpMyAdmin导入CSV时遇到的坑:

  1. 选择CSV using loading data
  2. 编码问题:遇到GBK编码文件需要先转换
  3. 特殊字符:处理了奖项名称中的emoji符号

5. 核心SQL查询

最终使用的查询方案:

SELECT 
    t.team,
    t.name AS member,
    COUNT(a.id) AS award_count,
    GROUP_CONCAT(DISTINCT a.award SEPARATOR ' | ') AS awards
FROM teams t
LEFT JOIN awards a ON 
    a.name = t.name OR
    a.name LIKE CONCAT(t.name, '%') OR
    a.name LIKE CONCAT('%', t.name, '%')
GROUP BY t.team, t.name
ORDER BY t.team, award_count DESC;

这个查询实现了:

  • 模糊姓名匹配(解决"张三"vs"张三丰"问题)
  • 多人共同获奖统计
  • 结果按团队和获奖数排序

技术难点与解决方案

挑战1:姓名模糊匹配

采用三级匹配策略:

  1. 精确匹配(a.name = t.name)
  2. 前缀匹配(LIKE '张三%')
  3. 包含匹配(LIKE '%张三%')

挑战2:多人共同获奖处理

-- 使用正则表达式拆分多人情况
SELECT 
    t.name,
    REGEXP_SUBSTR(a.award, '[^、]+', 1, 1) AS first_award
FROM awards a
JOIN teams t ON a.award LIKE CONCAT('%', t.name, '%')
WHERE a.award LIKE '%、%'

性能优化

  1. 为所有关联字段添加索引
  2. 使用EXPLAIN分析查询计划
  3. 对大表进行分区处理

成果展示

统计结果样例

团队 成员 获奖数 主要奖项
人工智能 王伟 5 最佳论文奖 技术创新奖
大数据 李娜 3 数据分析金奖

效率对比

方法 耗时 准确率 可维护性
Excel手工 6h+ 约60%
SQL方案 2h 98%

经验总结

  1. 技术选型:熟悉的工具(MySQL)胜于新潮技术(MongoDB)
  2. 数据清洗:占用了70%时间,印证了"垃圾进垃圾出"原则
  3. SQL优势:复杂关联查询是关系型数据库的杀手锏
  4. 自动化思维:能用代码解决的绝不手动操作

最意外的收获: 女友的百万崇拜,以及猫猫表情包 🐕男友价值 +10086 😎 感谢不嘲笑我技术宅的女朋友,虽然她至今不明白LEFT JOIN的原理

这次经历再次证明:在学校信息化水平不足的地方,技术就是最好的赚钱工具!

最终技术栈:

本文由deepseek润色而成,但确实是遇到的一个真实的问题,deepseek写的比较有趣,就放上来了