☰
Access 2007数据分析实战:聚合查询、操作查询与数据清洗技巧
2026/10/11 20:35:04 网站建设 项目流程

简介:本资源是面向Access用户的数据分析进阶读物,由微软认证应用程序开发师迈克尔·亚历山大撰写,适合希望从Excel转向关系型数据库、提升数据处理与查询能力的初中级读者。内容先对比Access与Excel在可扩展性、分析透明度、数据与呈现分离、数据规模与结构演变等方面的差异,再系统讲解表格创建、数据类型、数据导入、关系型数据库概念与查询基础,并深入聚合查询、操作查询(制表、删除、追加、更新)及交叉表查询的创建与使用。数据转换部分覆盖查找删除重复记录、填充空白字段、字段连接、文本与大小写转换、去除首尾空格、查找替换等常见任务。资源包为1个PDF文件,大小约11.35MB,结构完整便于通读与检索。目前已有78人学习,适合需要系统掌握Access 2007数据分析技巧、对照案例查漏补缺的读者。

1. 为什么 2024 年我还在翻这本 Access 2007 数据分析的老书

上周帮一家做医疗器械的客户清理他们积压了六年的销售台账,对方发来一个 1.2GB 的.accdb文件,里面 47 张表、两百多个查询,Excel 打开直接卡死,Python 读出来字段类型全是乱的。我花了三个晚上把这份《Microsoft Access 2007 Data Analysis》重新翻了一遍,用书里的聚合查询和操作查询思路把数据拆成了可分析的宽表。这不是怀旧,是 Access 在中小规模结构化数据分析上依然有它不可替代的位置——尤其是当你面对的是业务人员自己维护的、字段命名混乱、关系没建全的“野生数据库”时。

这本书的作者 Michael Alexander 是微软认证应用程序开发师(MCAD),有超过 14 年办公解决方案咨询经验,书由 Wiley 在 2007 年出版,ISBN 978-0-470-10485-9。它不讲花哨的 BI 看板,而是把 Access 当作一个数据分析引擎来用:从表结构设计、数据类型选择,到聚合查询、操作查询、交叉表查询,再到数据清洗转换的完整链路。适合两类人:一是手里有 Access 数据库但只会“打开表看看”的业务分析师,二是需要用 SQL 在 Access 里做数据预处理的工程师。如果你正在搜“Access 数据分析”“Access 查询技巧”“Access 数据转换”,这篇笔记会把书里的核心方法拆成能直接抄的步骤。

2. 把 Access 当分析引擎:表结构与查询基础

2.1 为什么选 Access 而不是 Excel 做分析

书里第一章就抛出一个反直觉结论:数据量超过 5 万行、需要多表关联、或者分析过程需要反复复用时,Excel 的“一张大表打天下”模式会迅速崩溃。Access 的优势不在可视化,而在四件事:可扩展性(单表百万行级别仍可查询)、分析过程透明(查询逻辑以 SQL 形式保存,可审计)、数据与呈现分离(表存数据,查询和报表各司其职)、以及共享处理(多人可同时连接同一个.accdb或.mdb)。

我自己的血泪经验是:Excel 里用 VLOOKUP 做多表关联,数据量一大就卡,而且公式藏在单元格里,换个人根本看不懂。Access 的查询把关联逻辑显式写出来,改起来有迹可循。书里特别强调“数据演变”这个概念——业务规则会变,今天按产品分类,明天可能按区域分类,Access 的查询可以随时改,Excel 的透视表改起来就费劲得多。

2.2 表结构设计与数据类型选择

Access 2007 的数据类型比 Excel 严格得多,这是好事也是坑。书里列了常用类型:文本(短文本 255 字符)、备注(长文本)、数字(字节/整型/长整型/单精度/双精度/小数)、日期/时间、货币、自动编号、是/否、OLE 对象、超链接、附件。做数据分析时,数值字段尽量用“双精度”或“小数”,避免用“单精度”导致聚合时精度丢失;日期字段一定用“日期/时间”而不是文本,否则排序和日期函数全废。

建表时我一般会做三件事:第一,给每张表设一个“自动编号”主键,哪怕业务上不需要,也方便后续做追加查询和去重;第二,字段名用英文或拼音,避免空格和特殊字符,否则写 SQL 时要加方括号,容易漏;第三,对经常用于关联和筛选的字段建索引,但不要滥用,索引会拖慢追加查询的速度。

-- 在 Access 查询设计器的 SQL 视图中创建一张分析用的客户表 CREATE TABLE tbl_Customer ( CustomerID AUTOINCREMENT PRIMARY KEY, -- 自动编号主键,追加查询时自动生成 CustomerName TEXT(100), -- 短文本,最多 100 字符 Region TEXT(50), -- 区域,用于分组聚合 OrderDate DATETIME, -- 日期时间,支持日期函数 OrderAmount DOUBLE, -- 双精度,避免聚合精度丢失 IsActive YESNO -- 是/否,布尔筛选 );

这段 SQL 可以直接在 Access 的查询设计器里切换到 SQL 视图执行。AUTOINCREMENT对应 Access 的“自动编号”,DOUBLE对应“双精度”,YESNO对应“是/否”。注意 Access 的CREATE TABLE不支持IF NOT EXISTS,重复执行会报错,我一般先DROP TABLE再建,或者手动在导航窗格里删。

2.3 数据导入与关系型数据库概念

书里花了很大篇幅讲数据导入,因为这是分析的第一步。Access 2007 支持从 Excel、文本文件、CSV、其他 Access 数据库、ODBC 数据源导入。我常用的路径是“外部数据”选项卡 → “导入”组 → 选择文件类型 → 指定工作表或分隔符 → 设置主键 → 命名表。导入时最容易翻车的是 CSV 的编码和日期格式:中文 CSV 用 UTF-8 带 BOM 时 Access 可能识别成乱码,我一般先用记事本另存为 ANSI,或者用 Excel 打开再另存为.xlsx再导入。

关系型数据库的核心是“关系”,书里用“客户-订单-订单明细”三张表举例:客户表存客户信息,订单表存订单头,订单明细存每个订单里的产品行。三张表通过外键关联,查询时用 JOIN 把数据拼起来。Access 的“关系”窗口可以拖拽字段建立一对多关系,并勾选“实施参照完整性”。我建议勾上“级联更新”和“级联删除”,但生产环境慎用级联删除,容易误删。

-- 用 INNER JOIN 把客户、订单、订单明细拼成一张分析宽表 SELECT c.CustomerName, c.Region, o.OrderDate, od.ProductName, od.Quantity, od.UnitPrice, od.Quantity * od.UnitPrice AS LineTotal -- 计算字段,Access 支持在查询里直接算 FROM (tbl_Customer AS c INNER JOIN tbl_Order AS o ON c.CustomerID = o.CustomerID) INNER JOIN tbl_OrderDetail AS od ON o.OrderID = od.OrderID WHERE o.OrderDate >= #2024-01-01# -- Access 日期常量用 # 包裹 AND c.IsActive = True;

Access 的 JOIN 嵌套需要用括号明确优先级,否则会报“FROM 子句语法错误”。日期常量用#而不是单引号,这是 Access 特有的。LineTotal是计算字段,Access 查询里可以直接做四则运算,不需要像 SQL Server 那样用子查询或 CTE。

3. 聚合查询与操作查询:从汇总到批量改数

3.1 聚合查询:GROUP BY 与 HAVING 的实战

聚合查询是数据分析的核心。书里把聚合查询拆成“分组字段”和“聚合函数”两部分:分组字段放在GROUP BY后面,聚合函数包括SUM、AVG、COUNT、MAX、MIN、STDEV、VAR等。Access 查询设计器里有一个“总计”按钮(Σ),点一下就会把普通查询变成聚合查询,每个字段的“总计”行可以选择Group By、Sum、Avg、Count等。

我经常用聚合查询做“按区域按月汇总销售额”:

SELECT c.Region, Format(o.OrderDate, 'yyyy-mm') AS OrderMonth, -- Format 函数把日期转成年月字符串 SUM(od.Quantity * od.UnitPrice) AS MonthlySales, COUNT(DISTINCT o.OrderID) AS OrderCount, -- Access 支持 COUNT(DISTINCT) AVG(od.Quantity * od.UnitPrice) AS AvgLineAmount FROM (tbl_Customer AS c INNER JOIN tbl_Order AS o ON c.CustomerID = o.CustomerID) INNER JOIN tbl_OrderDetail AS od ON o.OrderID = od.OrderID WHERE o.OrderDate BETWEEN #2024-01-01# AND #2024-12-31# GROUP BY c.Region, Format(o.OrderDate, 'yyyy-mm') HAVING SUM(od.Quantity * od.UnitPrice) > 10000 -- HAVING 过滤聚合后的结果 ORDER BY c.Region, OrderMonth;

Format函数是 Access 特有的日期格式化方式,'yyyy-mm'会输出“2024-01”这样的字符串。COUNT(DISTINCT o.OrderID)在 Access 里需要写COUNT(DISTINCT ...),但注意 Access 的DISTINCT在COUNT里只对单个字段有效,多字段去重需要子查询。HAVING和WHERE的区别是:WHERE在分组前过滤行,HAVING在分组后过滤组。我见过有人把条件写在WHERE里导致聚合结果不对,这是经典坑。

3.2 操作查询:制表、删除、追加、更新

操作查询是 Access 区别于 Excel 的杀手锏。书里讲了四种:制表查询(SELECT INTO)、删除查询(DELETE)、追加查询(INSERT INTO)、更新查询(UPDATE)。这些查询会真正修改数据,所以执行前一定要备份.accdb文件,或者先用SELECT预览结果。

制表查询把查询结果写入一张新表,适合做数据快照:

-- 把 2024 年销售汇总结果写入一张新表 tbl_SalesSummary2024 SELECT c.Region, Format(o.OrderDate, 'yyyy-mm') AS OrderMonth, SUM(od.Quantity * od.UnitPrice) AS MonthlySales INTO tbl_SalesSummary2024 FROM (tbl_Customer AS c INNER JOIN tbl_Order AS o ON c.CustomerID = o.CustomerID) INNER JOIN tbl_OrderDetail AS od ON o.OrderID = od.OrderID WHERE o.OrderDate BETWEEN #2024-01-01# AND #2024-12-31# GROUP BY c.Region, Format(o.OrderDate, 'yyyy-mm');

追加查询把一张表的数据追加到另一张结构相同的表:

-- 把 2025 年 1 月的数据追加到汇总表 INSERT INTO tbl_SalesSummary2024 (Region, OrderMonth, MonthlySales) SELECT c.Region, Format(o.OrderDate, 'yyyy-mm') AS OrderMonth, SUM(od.Quantity * od.UnitPrice) AS MonthlySales FROM (tbl_Customer AS c INNER JOIN tbl_Order AS o ON c.CustomerID = o.CustomerID) INNER JOIN tbl_OrderDetail AS od ON o.OrderID = od.OrderID WHERE o.OrderDate BETWEEN #2025-01-01# AND #2025-01-31# GROUP BY c.Region, Format(o.OrderDate, 'yyyy-mm');

更新查询用来批量改数,比如把所有“区域”为空的客户改成“未知”:

-- 把 Region 为空的记录更新为 '未知' UPDATE tbl_Customer SET Region = '未知' WHERE Region IS NULL OR Region = '';

注意 Access 的UPDATE不支持JOIN,如果要根据另一张表更新,需要用子查询或者DLookup函数。我一般用DLookup做小批量更新,大批量还是导出到 Excel 处理再导回来更快。

3.3 交叉表查询:行转列的 Access 方案

交叉表查询相当于 Excel 的透视表,但用 SQL 实现。书里专门用一章讲交叉表,因为它在做“区域×月份”这种二维汇总时非常高效。Access 的交叉表查询用TRANSFORM ... PIVOT ...语法:

TRANSFORM SUM(od.Quantity * od.UnitPrice) AS MonthlySales SELECT c.Region FROM (tbl_Customer AS c INNER JOIN tbl_Order AS o ON c.CustomerID = o.CustomerID) INNER JOIN tbl_OrderDetail AS od ON o.OrderID = od.OrderID WHERE o.OrderDate BETWEEN #2024-01-01# AND #2024-12-31# GROUP BY c.Region PIVOT Format(o.OrderDate, 'yyyy-mm');

TRANSFORM后面跟聚合函数,SELECT后面跟行字段,PIVOT后面跟列字段。Access 的交叉表查询最多支持 255 个列,超过会报错。如果列太多,我一般先按季度或年份汇总,减少列数。另外PIVOT的列名是动态生成的,不能直接用WHERE筛选,需要在外层再包一层查询。

4. 数据转换与清洗:查找重复、填充空白、文本处理

4.1 查找和删除重复记录

书里把“查找重复记录”作为数据转换的第一课,因为业务系统导出的数据经常有重复。Access 的“查找重复项查询向导”可以快速找出重复,但更灵活的方式是写 SQL:

-- 找出 CustomerName + Region 组合重复的记录 SELECT CustomerName, Region, COUNT(*) AS DupCount FROM tbl_Customer GROUP BY CustomerName, Region HAVING COUNT(*) > 1;

找到重复后,删除重复记录需要保留一条。我一般用“自动编号”主键来删:保留CustomerID最小的那条,删掉其他:

-- 删除 CustomerName + Region 重复的记录,只保留 CustomerID 最小的 DELETE FROM tbl_Customer WHERE CustomerID NOT IN ( SELECT MIN(CustomerID) FROM tbl_Customer GROUP BY CustomerName, Region );

这个DELETE语句在 Access 里执行前一定要先SELECT预览,确认要删的行数。Access 的DELETE不支持LIMIT,所以只能靠子查询控制范围。如果表很大,建议先建一张临时表存要保留的记录,再清空原表,最后把临时表追加回去。

4.2 填充空白字段与字段连接

空白字段在分析时会导致聚合结果偏差。书里给了两种填充方式:用固定值填充,或者用另一张表的值填充。固定值填充用UPDATE:

-- 把 Region 为空的记录填充为 '未知' UPDATE tbl_Customer SET Region = '未知' WHERE Region IS NULL OR Region = '';

用另一张表的值填充,我一般用DLookup:

-- 根据 CustomerID 从 tbl_RegionMap 里查区域,填充到 tbl_Customer UPDATE tbl_Customer SET Region = DLookup('Region', 'tbl_RegionMap', 'CustomerID = ' & tbl_Customer.CustomerID) WHERE Region IS NULL OR Region = '';

DLookup的第三个参数是条件字符串,注意字符串拼接用&,数字直接拼,文本要加单引号。DLookup在数据量大时性能很差,几万行以上建议导出到 Excel 用 VLOOKUP 或 Python 处理。

字段连接用&或+,&会把NULL当空字符串,+遇到NULL返回NULL。我一般用&:

-- 把 Region 和 CustomerName 拼成一个字段 SELECT Region & '-' & CustomerName AS RegionCustomer FROM tbl_Customer;

4.3 文本转换:大小写、去空格、查找替换

书里列了一组文本函数:UCase、LCase、Trim、LTrim、RTrim、Replace、InStr、Left、Right、Mid。这些在数据清洗时非常常用。比如把客户名统一转大写:

UPDATE tbl_Customer SET CustomerName = UCase(CustomerName);

去掉首尾空格:

UPDATE tbl_Customer SET CustomerName = Trim(CustomerName);

查找并替换特定文本:

-- 把 CustomerName 里的 '有限公司' 替换成 '公司' UPDATE tbl_Customer SET CustomerName = Replace(CustomerName, '有限公司', '公司') WHERE CustomerName LIKE '%有限公司%';

LIKE在 Access 里用*和?作为通配符,而不是%和_。Replace函数在 Access 2007 里可用,但早期版本可能需要用Mid和InStr组合实现。我一般先用SELECT预览替换结果,确认无误再UPDATE。

5. 避坑与排查:Access 数据分析的五个常见翻车点

5.1 现象:查询报“参数太少”或“数据类型不匹配”

原因:JOIN 的字段类型不一致,比如一边是“文本”,一边是“数字”;或者日期常量没用#包裹。解决:用SELECT先查两张表的字段类型,确保一致;日期常量写成#2024-01-01#;文本常量用单引号。

5.2 现象:追加查询报“键冲突”或“字段数不匹配”

原因:目标表有主键或唯一索引,追加的数据主键重复;或者INSERT INTO的字段列表和SELECT的字段数不一致。解决:追加前先删掉目标表的主键,或者用AUTOINCREMENT让 Access 自动生成;字段列表和SELECT字段一一对应,数量一致。

5.3 现象:交叉表查询列太多,报“太多字段”

原因:PIVOT的列字段基数太大,比如按天汇总一年有 365 列。解决:把列字段改成按月或按季度;或者先筛选时间范围,减少列数;Access 交叉表最多 255 列。

5.4 现象:DLookup更新几万行时卡死

原因:DLookup是逐行查询,每行都执行一次,性能极差。解决:导出到 Excel 用 VLOOKUP,或者用 Python 的 pandas 做 merge,再导回 Access;如果非要在 Access 里做,先建索引,或者用UPDATE ... INNER JOIN的替代写法(Access 不支持UPDATE JOIN,但可以用子查询)。

5.5 现象:导入 CSV 后中文乱码

原因:CSV 编码是 UTF-8,Access 默认按 ANSI 解析。解决:用记事本打开 CSV,另存为 ANSI 编码;或者先用 Excel 打开 CSV,另存为.xlsx,再导入 Access。如果数据里有特殊字符,导入时指定代码页 936(简体中文)。

6. 进阶技巧:用 Access 查询做数据验证与自动化

书里最后一章讲的是“把 Access 查询嵌入到分析流程里”,我把它落地成一个具体技巧:用 Access 查询做数据验证,确保导入的数据符合业务规则。比如订单金额不能为负、订单日期不能晚于今天、客户区域必须在预定义列表里。这些验证用SELECT查询实现,返回违规记录:

-- 数据验证查询:找出所有违规记录 SELECT '订单金额为负' AS ViolationType, OrderID, OrderAmount FROM tbl_Order WHERE OrderAmount < 0 UNION ALL SELECT '订单日期晚于今天' AS ViolationType, OrderID, OrderDate FROM tbl_Order WHERE OrderDate > Date() UNION ALL SELECT '客户区域不在预定义列表' AS ViolationType, c.CustomerID, c.Region FROM tbl_Customer AS c WHERE c.Region NOT IN (SELECT Region FROM tbl_RegionList);

UNION ALL把多个验证结果拼在一起,Date()返回当前日期。这个查询可以保存为“qry_DataValidation”,每次导入新数据后运行一次,有结果就说明数据有问题。我一般还会在 Access 里建一个宏,把导入、验证、汇总查询串起来,一键执行。

另一个技巧是用 Access 的“生成表查询”做数据快照,配合 Windows 任务计划程序实现定时分析。具体做法:把.accdb放在共享目录,写一个 VBScript 调用Access.Application打开数据库并运行宏,然后用任务计划程序每天凌晨执行。这样业务人员早上来就能看到最新的汇总表。

' 用 VBScript 定时运行 Access 宏 Dim accessApp Set accessApp = CreateObject("Access.Application") accessApp.OpenCurrentDatabase "C:\Data\SalesAnalysis.accdb" accessApp.Run "mcr_DailyRefresh" ' 运行名为 mcr_DailyRefresh 的宏 accessApp.Quit Set accessApp = Nothing

这段 VBScript 保存为.vbs文件,用任务计划程序调用。mcr_DailyRefresh宏里可以包含导入、删除、追加、更新、生成表等一系列操作。注意 Access 宏在无人值守运行时可能弹出确认对话框,需要在宏设计器里把“操作查询”的“警告”关掉,或者用SetWarnings False。

从那以后我每次拿到新的 Access 数据库,都强制先跑一遍“数据验证查询”,确认没有违规记录再开始分析。这个习惯帮我省了至少三次返工。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询