ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Access 2007 数据分析实战:从Excel迁移到关系型数据库的避坑指南

Access 2007 数据分析实战:从Excel迁移到关系型数据库的避坑指南 简介《Access 2007数据分析技巧详解》由微软认证应用开发师迈克尔·亚历山大撰写面向希望用Access替代Excel完成深层数据处理的职场人士与数据分析初学者。书中系统比较了Access与Excel在可扩展性、分析透明度、数据与呈现分离、数据量及演变等方面的优势并从表格创建、数据类型、关系型数据库概念等基础入手逐步深入到聚合查询、操作查询和交叉表查询覆盖制表、删除、追加、更新等常见操作。数据转换部分还整理了查找删除重复记录、填充空白字段、字段连接、文本与大小写转换、去除首尾空格、查找替换特定文本等实用方法。资源内含1个PDF文件压缩包大小11.35MB可离线阅读原书全部内容。已有78人学习适合希望系统提升Access数据分析能力、掌握查询与数据清洗实战技巧的读者。1. Access 2007 数据分析一本讲方法的老书为什么现在还有人翻Access 2007 的资料在今天还能不能看很多人看到版本号就划走了但如果你翻过这本 Michael Alexander 写的《Microsoft Access 2007 数据分析》会发现它几乎不讲界面特效整本书都在讲一个更值钱的东西怎么用关系型数据库的思路把原始数据变成可决策的结论。作者是微软认证应用程序开发师MCAD有十四年办公解决方案咨询经验书里关于数据建模、聚合查询、操作查询、交叉表和数据清洗的方法放到现在的 Access 365 上依然成立。适合谁在 Excel 里被几十万行数据卡到崩溃、做分析全靠手动复制粘贴、想让查询过程透明可复用的人。接下来我把书里能直接落地的部分拆给你每一步都能照着跑。2. 为什么是 Access 而不是 Excel八个优势与数据建模的地基这本书开篇就把一个很多人不好意思问的问题摆在桌面上既然 Excel 这么顺手为什么还要用 Access 做数据分析作者给出的答案不是「因为 Access 更专业」这种空话而是从工作方式上列了八个差异。理解这八个差异你才能判断手里的活到底该不该迁移到 Access。2.1 八个优势从单元格里的黑匣子到看得懂的流水线Excel 的问题不在于算得慢而在于分析过程不可见。公式散落在各个单元格里别人看不懂三个月后的你自己也看不懂。Access 把分析拆成「表 → 查询 → 报表」三段每一段都是独立对象查询的 SQL 清清楚楚摆在那里谁接管都能顺着逻辑走一遍。这就是书里强调的「分析透明度」。与之相关的还有「数据与呈现分离」——Excel 一个 Sheet 里数据、计算结果、图表混在一起改一版报表往往要动整片区域Access 里表只负责存数查询只负责算数报表只负责展示各管一段。维度Excel 的表现Access 的做法可扩展性Excel 2007 之前单表只有 6 万多行2007 虽到 104 万行但大数据量下公式和透视明显变慢单表可支撑百万行分析在数据库引擎里跑分析透明度公式散落逻辑靠猜查询是命名对象SQL 可见可审数据与呈现分离Sheet 混着原始数据、公式、图表表、查询、报表三层分离数据大小内存吃紧文件一大人人喊卡文件上限约 2GB适合百万行内明细数据结构单元格什么都能塞脏数据难防字段类型与关系模型从入口约束数据数据演变需求一变公式矩阵跟着大改改一个查询定义结果即刻更新功能复杂性复杂统计要嵌套公式、辅助列聚合、连接、子查询、交叉表一步到位共享处理多人同时编辑容易冲突可拆分前后端数据库多人并发更稳这八条里最容易让人误判的是「数据大小」。很多人以为 Access 只适合几千行的数据其实 Access 单表能撑到百万行级别关键区别在于它把计算交给了数据库引擎而不是让 Excel 在内存里硬扛。书里写这本书时的对照版本是 Excel 2003 和刚出的 2007现在你用 Excel 365 也一样只要数据超过十几万行、筛选和透视开始转圈就是该考虑 Access 的时候。2.2 表设计字段类型是第一道数据校验数据分析的地基是表不是查询。表设计错了后面所有查询都是在脏数据上做算术。创建表可以直接在设计视图里画也可以用 SQL 一次性建好CREATE TABLE 销售明细 ( 订单ID COUNTER PRIMARY KEY, 客户名称 TEXT(50), 订单日期 DATETIME, 销售额 CURRENCY, 销售区域 TEXT(20) );COUNTER 是 Access 的自增字段用它做主键最省心不用手动维护编号。TEXT(50) 表示最长 50 个字符的短文本DATETIME 存日期时间CURRENCY 是货币类型内部按精确小数存储。这里最容易犯的错是把「销售额」设成数字类型里的双精度——浮点数在累加时会有精度损失几万行加起来可能差出几毛钱银行和财务对不上账的根源往往在这。金额用 CURRENCY 不用 DOUBLE是这本书反复强调的习惯。字段命名也要克制。不要用 Name、Date、Value、Year 这类名字它们和 Access 内置函数、保留字撞名写查询时会被迫加方括号[Date]才能跑纯粹给自己添堵。我一般用「业务含义 类型后缀」的写法比如 客户名称、订单日期、销售额中文命名在 Access 里完全合法反而比英文缩写更不容易产生歧义。2.3 主键与关系让表与表之间能对话表建好之后要做的不是急着导入数据而是先定义关系。进入「数据库工具 → 关系」把 客户表 的 客户ID 拖到 销售明细 的 客户ID 上勾选「实施参照完整性」一对多关系就建立了。实施参照完整性意味着销售明细里不能出现客户表里不存在的客户ID这个约束能从机制上挡住孤儿数据。分析场景里最常见的模型是「事实表 维度表」——销售明细是事实表客户表、产品表是维度表查询时通过主外键把它们连起来SELECT a.客户名称, b.销售额 FROM 客户表 AS a INNER JOIN 销售明细 AS b ON a.客户ID b.客户ID;这里有个细节会在后面坑到你连接字段的类型必须一致。一个表里客户ID是长整型另一个表里客户ID是文本型JOIN 会直接匹配不上或者匹配结果诡异。每次建关系前我都先看两边的字段类型类型不一致就先改表结构不要想着在查询里用函数转——能用结构解决的问题不要用逻辑去兜底。3. 把数据放进去导入、字段类型与 SELECT 查询的地基3.1 从 Excel 和 CSV 导入先解决数据怎么进来Access 虽然有自己的表设计能力但绝大多数分析项目的数据源头还是 Excel 和 CSV。导入路径很简单「外部数据 → 从 Excel 导入」向导会问你要新建表、追加到现有表还是创建链接表。第一次导入我建议选「新建表」让 Access 自己根据源数据推断字段类型导入完再进设计视图检查修正。「创建链接」适合数据不定期更新、想每次直接读 Excel 最新内容的场景但链接表不能用操作查询改数据只能查。用代码导入更可控DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _ 销售明细, C:\Data\销售明细.xlsx, TrueacImport 表示执行导入acSpreadsheetTypeExcel12 对应 Excel 2007 及以后的 xlsx 格式第三个参数是目标表名第四个是源文件路径最后的 True 表示源文件第一行是列名。如果你用的是 .xls 老格式把第二个参数换成 acSpreadsheetTypeExcel97 即可。导入前先确认列名不重复、日期格式统一、没有整行空数据这些脏东西导入后会变成 NULL后面处理起来比在 Excel 里删还麻烦。原始 Excel 文件别动导进 Access 的那份才是你的工作副本改错了一键重来相当于给自己留了后悔药。3.2 数据类型选错类型后面全歪导入完成后立刻进设计视图检查字段类型这是全书默认动作。Access 里常见类型和坑位如下数据类型取值范围/存储分析用途容易踩的坑短文本最长 255 字符名称、编码、区域尾部空格常在关联前先 Trim长文本最长 65,535 字符备注、描述不适合做索引排序性能差字节0 到 255小数量255 一满就溢出报错整型-32,768 到 32,767中位量级数量超范围直接报溢出长整型约正负 21 亿ID、外键推荐的主键和外键类型双精度大范围浮点比率、大数小数累加有精度误差货币精确到 4 位小数所有金额别用双精度存钱日期/时间日期加时间时间维度Excel 导入常变成数字序列是/否True / False标记位判断用 True/False不是 1/0最伤的一个是日期列导入后变成 41023 这样的数字。原因是 Excel 内部把日期存成自 1900 年起的序列数导入向导推断不准就会按数字处理。解决办法是在 Excel 源文件里先把日期列格式统一成 YYYY-MM-DD再导入一次如果已经导入成数字了用 DateAdd 之类的方式救回来很麻烦不如回源头改格式重新导。来源数据永远不要手改改源头、重导入才是正路。3.3 查询基础设计视图和 SQL 视图是同一件事查询是 Access 数据分析的核心对象但很多人被「查询设计」这个界面框住了——拖拖拽拽拉字段、设置条件总觉得不如 Excel 里写公式顺手。换个思路设计视图只是 SQL 的可视化外壳你在网格里做的每一个动作都会翻译成 SQL 语句。直接切到 SQL 视图写反而更清楚SELECT 销售区域, SUM(销售额) AS 区域合计 FROM 销售明细 WHERE 订单日期 #2024-01-01# GROUP BY 销售区域 ORDER BY SUM(销售额) DESC;这条查询做的是先按 WHERE 过滤出 2024 年之后的订单再按 销售区域 分组用 SUM 算出每个区域的合计最后按合计降序排列。执行顺序是 FROM → WHERE → GROUP BY → SELECT → ORDER BYWHERE 一定在 GROUP BY 之前过滤行。Access 里的日期字面量用井号#2024-01-01#包起来这是和别的数据库差别最明显的地方SQL Server 里用单引号没问题拿到 Access 必须改成井号。设计视图里网格的每一列对应 SELECT 里的一个字段条件行对应 WHERE排序行对应 ORDER BY。如果你刚开始不熟 SQL可以在设计视图里搭条件、再切到 SQL 视图看生成的语句来回切几次就能把两者的对应关系摸透。不要停留在只会用设计视图的阶段——写复杂聚合和操作查询时SQL 视图的效率高得多。3.4 参数查询把写死的条件变成弹窗业务分析里最常用的一个技巧是参数查询。条件值不写死每次运行查询时弹出输入框让你填同一套查询既能跑 1 月的数据也能跑全年数据PARAMETERS [开始日期] DateTime, [结束日期] DateTime; SELECT 订单日期, 客户名称, 销售额 FROM 销售明细 WHERE 订单日期 BETWEEN [开始日期] AND [结束日期];PARAMETERS 声明了两个日期类型参数方括号里的文字就是运行时的提示语。参数类型一定要写不写的话 Access 会把输入内容当文本处理日期比较就可能出错。这个功能在给同事做数据模板时非常实用——对方不懂 SQL双击查询、填两个日期、看结果整个过程零学习成本。书里的聚合查询与数据转换部分频繁使用这样的查询做中间步骤先把查询存好才能在上面继续叠加别的操作。4. 聚合与操作查询把明细变成结论的四种写法和一个透视4.1 聚合查询GROUP BY 是所有统计的起点明细数据只有汇总才有分析价值。Access 的聚合查询用 GROUP BY 配合聚合函数完成写法和标准 SQL 基本一致SELECT 产品类别, COUNT(*) AS 订单笔数, SUM(销售额) AS 总销售额, AVG(销售额) AS 客单价 FROM 销售明细 GROUP BY 产品类别 HAVING SUM(销售额) 10000;COUNT() 统计的是行数只要行存在就计数COUNT(字段名) 则忽略该字段为 NULL 的行两者结果可能不一样——想知道某个字段到底缺了多少值用 COUNT(字段) 对比 COUNT() 就能算出来。SUM 和 AVG 会自动忽略 NULL这一点符合 SQL 标准但它会让结果看起来「少了」——具体坑位我在下一章展开。HAVING 和 WHERE 的区别是WHERE 在分组前过滤明细行HAVING 在分组后过滤分组两者作用阶段不同不能互换。这里要习惯用别名的字段在 HAVING 里不能再引用别名要重写 SUM(销售额) 这种表达式Access 对标准 SQL 的兼容性在这一点上相当严格。4.2 操作查询从「看数据」到「改数据」要迈过的坎普通 SELECT 查询不改变数据操作查询则会。书里把这部分拆成制表查询、追加查询、更新查询、删除查询四类每一类都对应一个数据落地场景。制表查询SELECT INTO把查询结果固化成一张新表SELECT 客户ID, SUM(销售额) AS 总销售额 INTO 客户月度汇总 FROM 销售明细 GROUP BY 客户ID;跑完之后客户月度汇总 就成了一张独立表可以导出给 Excel 做透视或者提供给不懂 Access 的同事当数据源。注意这个查询每次运行都会删除同名表再重建存在覆盖风险名字起得有辨识度别和线上数据表混在一起。追加查询INSERT INTO SELECT把查询结果加到已有表尾部INSERT INTO 销售归档 (订单ID, 客户ID, 销售额, 订单日期) SELECT 订单ID, 客户ID, 销售额, 订单日期 FROM 销售明细 WHERE 订单日期 #2024-01-01#;这是做历史归档最顺手的方案把旧的明细查出来塞进归档表确认无误后再从原表删掉业务表始终保持当期数据。更新查询UPDATE按条件批量改值UPDATE 销售明细 SET 销售区域 华东 WHERE 省份 IN (上海, 江苏, 浙江);执行前永远先用相同 WHERE 跑一条 SELECT 看看影响范围这是操作查询的铁律。删除查询DELETE FROM ... WHERE同理删掉的数据不会进回收站。需要批量清数时它的效率比逐个删高几个量级但代价是手一抖就全没了。4.3 交叉表查询用 TRANSFORM 做一维透视聚合查询输出的是长表交叉表查询输出的是宽表——把某个字段的值变成列做矩阵式汇总。Access 里用 TRANSFORM ... PIVOT 实现TRANSFORM SUM(销售额) AS 合计 SELECT 产品类别 FROM 销售明细 GROUP BY 产品类别 PIVOT Month(订单日期);结果会生成一张表行是产品类别列是 1 到 12 月交叉点是当月销售额。PIVOT 后面的字段值决定列头的生成方式Month(订单日期) 会产出 1、2、3……这样的数字列名你也能换成 销售区域 让列变成区域名称。交叉表查询非常适合做销售矩阵和横向对比但要注意它的列数是动态的列头完全取决于 PIVOT 字段里实际出现的值不能人为固定列范围。数据里某个月没有订单那一列就不会出现视野上容易留下空白做正式报表前最好先确认数据完整性。5. Access 数据分析排查笔记五条血泪避坑记录Access 的问题很少出在语法上几乎全出在对执行行为的误判上。下面五条是从书里的数据转换和操作查询部分延伸出来的高频现场每一条我都见过不止一次翻车。5.1 更新查询全表被改WHERE 漏了就是事故现象跑一条更新查询本来只想改 3 条记录结果整表几千行的状态字段全变成了同一个值。原因WHERE 条件没写或者条件引用了 NULL 字段导致匹配了所有行。Access 执行 UPDATE 前会弹窗提示「即将更新 N 行」但那个数字一闪而过很多人瞄一眼就直接回车了。解决严格执行两遍流程——第一遍用相同的 WHERE 跑 SELECT 看返回行数第二遍确认行数无误再把 SELECT 换成 UPDATE。备份的习惯也要跟上执行前右键表名复制粘贴一个_backup副本不占多少空间值一条命。5.2 SUM 结果对不上总额NULL 在捣乱现象手工在 Excel 里加总一个字段是 100 万Access 里 SUM 出来是 98 万怎么都对不上。原因Access 的 SUM 忽略 NULLExcel 的 SUM 也忽略 NULL但 Excel 的空单元格和 Access 的 NULL 不是一回事——导入时 Excel 里的空行变成 NULLAccess 直接跳过而你在 Excel 里看那几行是空的以为没值其实格式里藏着 0 或者空格。解决用 NZ 函数把 NULL 显式归零然后对比差异SELECT SUM(NZ(销售额, 0)) AS 实际合计 FROM 销售明细;更稳的做法是导入后先专门查一遍空值SELECT COUNT(*) FROM 销售明细 WHERE 销售额 IS NULL;在有 NULL 的字段上做任何聚合结果都要打问号。5.3 删除查询没有后悔药Access 不是 Excel现象执行了一条 DELETE数据没了想 CtrlZ 撤销发现根本没有撤销这回事。原因Access 的删除查询是物理删除不走回收站也没有事务回滚界面。解决删除前先把目标数据备份成一张表——SELECT * INTO 待删除备份 FROM 销售明细 WHERE 订单日期 #2020-01-01#;——确认备份行数和删除行数一致后再执行 DELETE。开了参照完整性且勾选了级联删除的关系删主表会连带删掉子表记录这个连锁反应比单表删除更隐蔽动手前检查一下关系窗口里的设置。5.4 导入后日期变数字、文本变乱码现象从 Excel 导入后日期列显示成 41023 这种数字中文文本出现问号或乱码。原因Excel 内部日期就是序列数导入向导类型推断失误就会按数字处理CSV 文件编码不对时中文字符会解码失败。解决源头文件先把日期列设成文本并统一为 YYYY-MM-DD 格式导入向导走到字段类型那一步时手动把日期字段指定为「日期/时间」不要信任自动推断。CSV 文件用记事本打开检查编码另存为 ANSI 编码再导入UTF-8 带 BOM 的 CSV 在 Access 2007 里尤其容易出乱码。5.5 字段名撞保留字、LIKE 通配符查不出数据现象查询里用了 日期、名称 之类的字段名保存时提示「与保留字冲突」写 LIKE 条件LIKE %袜子%查出来却是零行。原因Name、Date、Year、Value 是 Access 的保留字和内嵌函数名裸写会冲突Access 查询默认的 LIKE 通配符是*和?不是 SQL 标准里的%和_。解决冲突字段加方括号[Date]能临时跑通但最好进设计视图改成 订单日期 这种不撞车的名字一劳永逸。通配符按 Access 方言来LIKE *袜子*才是对的只有当你用 ADO 连接并开启了 ANSI-92 查询模式时%才生效。先确认自己运行 SQL 的环境再写通配符省得来回试。6. 数据转换的落地技巧去重、补空与字段拼接书的后半部分花了不少篇幅讲数据转换这些动作不炫技但日常分析里几乎天天要用。挑三个最高频的展开。查找和删除重复记录是数据清洗的起点。先让重复项现身SELECT 客户邮箱, COUNT(*) AS 出现次数 FROM 客户表 GROUP BY 客户邮箱 HAVING COUNT(*) 1;HAVING 把出现次数大于 1 的邮箱揪出来这一步只查不删先看数量和分布。确认哪些是重复项后再决定保留哪一条、按什么规则删不要直接 DELETE——重复记录里可能混着内容不完全相同的行删错了信息就丢了。填充空白字段处理的是 NULL 参与运算的问题。把 NULL 显式补成 0聚合结果才可信UPDATE 销售明细 SET 销售额 0 WHERE 销售额 IS NULL;字段拼接和文本清洗是导出报表前的常规动作。Access 里拼接会把 NULL 当空字符串处理拼接遇到 NULL 则整个结果变 NULL想拼出「省份 - 城市」这种完整地址用更符合直觉。配合 Trim 去掉首尾空格、StrConv 做大小写转换文本字段的匹配成功率会明显提升。查找替换指定文本时用 Replace 函数加 WHERE 条件做精准更新别用界面上那个全表查找替换后者范围不可控。我从那以后给自己定了一条规矩任何数据进入查询之前强制走一遍「去重 → 补空 → Trim → 统一编码」的流程哪怕只是临时分析也不跳过。这套动作治好了我大部分脏数据焦虑——Access 2007 虽然版本老但数据转换的思路在任何时代都不过时。如果你也在和 Excel 导出的数据较劲希望这本书里的方法能帮你少走一段弯路。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进