每个月最折腾的不是算数,而是把十几份格式各异的表合成一份。合并、去重、对齐列名、再按条件筛选——这些动作足够稳定,也足够无聊,正是应该交给程序的部分。

#为什么要换成数据库

Excel 的问题不在功能,而在"多人同时改"这件事上:

场景 Excel SQLite
多人协作 靠传文件,版本容易乱 单文件 + 事务,写入安全
数据量上万行 卡顿、公式重算慢 毫秒级
复杂筛选 层层透视表 一条 SQL
和程序对接 需要额外解析 原生查询

结论:数据量小但逻辑复杂时,SQLite 比 Excel 更省心。

#迁移的第一步:让结构稳定下来

先把字段固定成一张表,别怕冗余,先跑起来再说:

import sqlite3, pandas as pd

conn = sqlite3.connect("school.db")
conn.execute("""
CREATE TABLE IF NOT EXISTS salary (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    month TEXT NOT NULL,
    amount REAL NOT NULL,
    created_at TEXT DEFAULT (datetime('now','localtime'))
)
""")

df = pd.read_excel("10月工资.xlsx")
df = df.rename(columns={"姓名": "name", "月份": "month", "实发金额": "amount"})
df[["name", "month", "amount"]].to_sql("salary", conn, if_exists="append", index=False)
print("导入", len(df), "行")

#几个立刻能用的查询

  • 查某人全年发放合计:SELECT name, SUM(amount) FROM salary GROUP BY name
  • 找重复导入的记录:SELECT name, month, COUNT(*) c FROM salary GROUP BY name, month HAVING c > 1
  • 按月出汇总:SELECT month, SUM(amount) FROM salary GROUP BY month ORDER BY month

#踩过的坑

  1. 中文列名:建表时用英文,展示层再映射,省掉一堆转义问题。
  2. 日期类型:SQLite 没有真正的日期类型,统一存 YYYY-MM-DD 字符串,排序才正确。
  3. 多次导入:给业务键加唯一索引,用 INSERT OR REPLACE 保证可重复执行。
CREATE UNIQUE INDEX IF NOT EXISTS idx_salary_unique ON salary(name, month);

#小结

把数据从"文件"搬到"数据库",最大的收益不是速度,而是可复用:同一份数据能被脚本、报表、网页同时读取,而不是每次都重新手工整理一遍。