
简介这份《Power Query入门手册》是一份面向Excel报表自动化初学者的PDF指南系统讲解Power QueryPQ的数据预处理方法涵盖从文本/CSV/Excel等数据源的获取、清洗、转换到合并查询的全流程帮助用户摆脱手工复制粘贴高效完成数据导入与整理。手册共1个PDF文件约3.13MB内容组织清晰从入门案例到数据清洗十招循序渐进覆盖文件导入、M函数、添加自定义列与条件列、逆透视、分组依据、追加查询、模糊查询等操作并配有具体应用步骤说明。已有4577人学习查看适合希望提升Excel数据分析效率、快速上手PQ的办公人群。通过这本手册读者可掌握数据导入、清洗、转换和组合的核心技能建立系统的数据预处理工作流。1. Power Query 入门手册为什么说它比函数公式更值得你花时间先抛一个反直觉的结论Power Query 入门手册里最该先理解的不是某个具体功能按钮而是“你在界面里的每一次操作都会被自动记录成一段可回放的 M 公式”这件事。很多从业者以为 Power Query 只是 Excel 里多了一个叫“获取数据”的菜单实际上它是一套独立的数据整理引擎专门把粘贴、复制、查找替换这类重复劳动变成一次建立、之后每次一键刷新就能重跑的流程。我见过太多人还在用 VLOOKUP 串表、用复制粘贴合并十几个报表其实这些活交给 Power Query半小时能建成一个能用一年的清洗模板。这份手册适合谁如果你每天要处理多个工作表、格式不统一的 CSV、甚至要连数据库做报表但每次都被数据清洗拖住它就是你的后悔药。新手可以按章节从零搭一条完整的数据加工流水线已经用过一段时间的人也能在“查询折叠”“参考查询”“错误处理”这些细节里找到自己之前没完全捋清的环节。整本手册只讲一个核心怎么在 Power Query 里把脏数据变成结构稳定、可以反复刷新的数据源而不是去背那些永远记不住的函数。2. 理解 Power Query 的底层机制查询列表、步骤和 M 公式2.1 查询列表是什么一个查询就是一条可回放的数据加工线打开 Excel切到“数据”选项卡点“获取数据”→“启动 Power Query 编辑器”你会看到左侧有一块“查询”窗格中间是数据预览区右侧是“查询设置”。这套布局和 Excel 主界面完全不一样初次接触会觉得陌生但它对应的其实是数据加工的思路左侧管“有哪些加工任务”中间管“当前数据长什么样”右侧管“这个任务已经做了哪些步骤”。一个查询就是一条完整的数据加工线。它可以从一张 Excel 表开始也可以从一个文件夹下的几百个文件开始甚至可以从数据库里的某个视图开始。你后续做的每一步——删列、改类型、筛选、分组、合并——都会依次记录在“已应用步骤”里。这个步骤列表不是临时日志它是这条加工线的施工图纸记录了你对数据做了哪些操作、按什么顺序做。值得注意的一点是查询列表本身是可以重命名、复制、删除的。我一般会建议团队里每个人给查询起“看得懂的名字”比如“订单明细_清洗后”而不是默认的“查询1”。因为当查询数量超过十个之后靠默认名称你根本分不清哪个是哪个。复制查询时也要小心右键菜单里有两个选项一个是“复制”一个是“创建参考”。复制会把当前所有步骤原样克隆一份之后互不影响创建参考则是新建一个查询它的源是这个查询的结果源一变它也跟着变。这两者的区别如果没搞清后面维护时会踩大坑我自己的血泪经验是做下游分析报表时优先用“创建参考”而不是复制因为复制会留下两套需要同时维护的清洗步骤。2.2 已应用步骤的本质每一步都吃上一步的“表”“已应用步骤”里每一行比如“删除的列”“筛选的行”“更改的类型”看起来像操作记录但它的本质是数据转换链上的一环。上一步输出的表会作为这一步的输入这一步输出的新表再传给下一步。整个过程中间看不到临时文件数据始终在内存里流动。理解了这个很多让新手迷惑的现象就能解释了。比如你在第 3 步删掉了“备注”列第 5 步又有一个基于“备注”列的筛选当你回头删除“删除的列”这个步骤时第 5 步会立刻报错。原因很简单第 5 步想要的字段在链条上游已经不存在了。Power Query 非常诚实它不会智能地猜测你想干什么只会按步骤顺序严格执行。还有一个新手容易忽略的地方步骤的顺序直接影响性能。同样是先筛选还是先改类型看起来结果一样但过程差异很大。比如一张 100 万行的表你先在“更改的类型”里把日期列改为日期格式再筛选某个月份的数据Power Query 会先把 100 万行全部做了类型转换再筛掉大部分行但如果先筛日期范围再改类型它只用处理筛剩下的几万行。这个习惯越早养成越好它比你后面学的任何优化技巧都管用。另外步骤名称是可以双击修改的。改成一个能表达意图的名字比如把“筛选的行”改成“筛选金额大于1000的行”对整个查询的可读性提升很大。尤其是交接工作时别人打开你的查询能直接看懂每一步在干什么。2.3 看懂 M 公式刷新一次就是完整的重放当你打开“视图”选项卡勾选“公式栏”就能在每一步的顶部看到对应的 M 公式。Power Query 的底层语言叫 M界面里的每次点击都会生成一段 M 表达式。你不用一开始就学写 M但必须能看懂它因为很多复杂的操作是在“高级编辑器”里手动改公式来完成的。看一个最简单也最常见的例子从 Excel 工作簿读取一个名为“订单”的工作表然后改类型、筛金额大于 100 的行let 源 Excel.Workbook(File.Contents(C:\data\orders.xlsx), null, true), 订单表 源{[Item订单, KindTable]}[Data], 更改的类型 Table.TransformColumnTypes(订单表, {{金额, type number}, {日期, type date}}), 筛选的行 Table.SelectRows(更改的类型, each [金额] 100) in 筛选的行逻辑并不复杂let开头in结尾中间每个等号左边是一个步骤名等号右边是这个步骤的表达式。每一步引用上一步的名字作为输入最后in后面的那个步骤名就是整个查询的输出。你看到的“已应用步骤”列表本质上就是这个 M 表达式的可视化外壳。注意几个关键参数Excel.Workbook的第二个参数null表示不把首行自动识别为标题第三个参数true表示使用表类型Table.TransformColumnTypes的参数是成对出现的列名和数据类型Table.SelectRows里的each表示对每一行执行后面括号里的逻辑。这些都值夜班。理解了刷新就是完整重放之后一个常见困惑就能解开为什么我在 Excel 里改了源数据单元格Power Query 表却不变因为查询默认读取的是你最初指定的源如果你用的是普通区域源是一个静态快照只有把源数据定义成“超级表”快捷键 CtrlT查询的源才会有动态引用的概念。刷新一次Power Query 就把从源到最后一步的所有逻辑从头执行一遍这也解释了为什么刷新按钮叫“刷新”而不是“更新”——它不是简单重算而是整条流水线重新跑一遍。3. 把数据接进来从工作表、CSV 文件夹到数据库的三种导入路线3.1 从当前 Excel 表导入先把普通区域转成超级表最常见的场景是数据已经躺在某个 Excel 文件里你要把它送进 Power Query。很多人直接在数据选项卡点“从表格/区域”结果弹窗提示“无法找到表格”然后就愣住了。原因很简单Power Query 不认普通区域只认“表”。所以标准的做法是先选中数据区域内任意一个单元格按 CtrlT 把它转成超级表。弹窗里确认“表包含标题”是否勾选因为默认情况下第一行会被当作列名。接着切到“数据”选项卡点“从表格/区域”Power Query 编辑器就会打开源数据已经变成了一个查询。这里有个细节值得多说一句超级表的名称会成为查询的“表名”之后你写 M 引用它时用的是这个表名。如果你换了表名之前查询里的引用会失效。另外超级表有个天生的优势你在源区域下方新增一行数据CtrlS 保存后Power Query 刷新时能自动把新行纳入范围但对普通区域来说因为源没有得到“表”这个身份新加的行在刷新时可能根本不被读取。这算是初学者最容易踏空的一步我见过不少同事卡在这个“无法找到表格”的弹窗上浪费了半小时。如果你要导入的 Excel 文件不是当前文件而是磁盘上的另一个文件操作路径略有不同在“数据”选项卡里选择“获取数据”→“来自文件”→“从 Excel 工作簿”然后浏览到目标文件。Power Query 会把工作簿里的每个工作表、每个命名区域、每个超级表都列出来你选中需要的那个即可。注意这时候查询读的是整个工作簿文件文件里任何一个表的改动刷新后都会体现在查询结果里。3.2 从文件夹批量导入格式一致的文件再多也不怕比单文件导入更让人头疼的是几十个格式一致但分散在不同子文件夹里的 CSV或者每个月一整套的 Excel 报表。传统做法是打开每个文件复制粘贴到汇总表重复又容易错。Power Query 的“从文件夹”导入就是为了解决这种批量需求。操作路径是“数据”→“获取数据”→“来自文件”→“从文件夹”然后在弹窗里填文件夹路径比如C:\data\orders。点击确定后Power Query 会生成一个查询里面列出了文件夹下所有文件的名称、路径、大小、修改时间等信息但还没有真正读取每个文件的内容。下一步才是关键点预览列的“合并”→“合并文件”它会让你选一个示例文件你用这个示例文件定义清洗步骤Power Query 会把这些步骤自动套用到所有文件上。这个机制看着很美但它默认要求文件夹里所有文件表结构一致。一旦某个文件多了一列或者某列类型变了刷新时就报错。所以我在做这类导入时一定会先对文件内容做一次“清洗兜底”不直接套用示例步骤典型做法是写一段自定义函数来统一处理每个文件。示例函数是这样的(文件路径 as text, 文件名 as text) let 源 Excel.Workbook(File.Contents(文件路径 文件名), null, true), 订单表 源{[Item订单, KindTable]}[Data], 清洗 Table.SelectColumns(订单表, {订单ID, 金额, 日期}), 类型修正 Table.TransformColumnTypes(清洗, {{金额, type number}, {日期, type date}}) in 类型修正然后在装配查询里用Folder.Files获取文件列表再调用这个函数let 文件列表 Folder.Files(C:\data\orders), 添加处理列 Table.AddColumn(文件列表, 已处理, each 处理文件([Folder Path], [Name])), 展开结果 Table.ExpandTableColumn(添加处理列, 已处理, {订单ID, 金额, 日期}, {订单ID, 金额, 日期}) in 展开结果逻辑解释Folder.Files返回一个包含每行一个文件的表Table.AddColumn给每个文件调用一次处理文件函数函数的两个参数分别是文件所在路径和文件名最后用Table.ExpandTableColumn把函数返回的表里的列展开到主查询里。这样即使某个文件多出无关列Table.SelectColumns也会把列集固定下来运行起来稳定得多。这里要给两个参数提醒一是函数参数顺序一定要和调用时一致否则很容易走出“文件名传错位”的故障二是each是按行重复的动作后面引用列名要加中括号写成[Folder Path]而不是Folder Path这一点新手几乎一定会写错一次。3.3 从数据库导入查询折叠是个好东西但别太迷信界面在企业里数据往往不是 Excel 文件而是落在数据库里。Power Query 连接数据库的方式和 Excel 文件不太一样它不只是拉数还承担了把计算下推给数据库的能力。进入路径是“获取数据”→“来自数据库”→“从 SQL Server 数据库”填服务器名和数据库名。如果你对 SQL 熟练也可以在“高级选项”里直接粘贴一段 SQL 作为查询源。常见的做法是连接后Power Query 会弹出导航器列出库里所有表和视图。你点选一个表它会在后台生成类似这样的 M 公式let 源 Sql.Database(server01, SalesDB), 订单表 源{[Schemadbo, ItemOrders]}[Data], 筛选状态 Table.SelectRows(订单表, each [Status] 已完成) in 筛选状态这段代码看起来只是读表和筛选实际上有个非常重要的性能机制叫“查询折叠”。Power Query 会尝试把自己的步骤翻译成 SQL 语句交给数据库服务器去执行而不是把所有数据拉回本地再过滤。所以你在界面里做的筛选、分组、选择列如果能被数据库执行查询的响应速度会快很多。但要注意不是所有步骤都能折叠。比如你加入了一个自定义列里面用到了某些复杂的自定义函数Power Query 可能被迫把前面的步骤也一并拉回来本地计算这时候你之前设的筛选条件就不生效了。想确认某个步骤是否还能折叠可以在该步骤上右键查看“本机查询”或“查看数据库查询”的可用性。为了让数据库查询尽量折叠我一般会在连接时就写好 WHERE 条件而不是把几百万行拉到 Power Query 里再筛。4. 清洗与转换拆分、合并、透视、分组四个一线高频动作4.1 拆分列和合并列解决文本型脏数据的两个反方向导入的数据经常带着一列里塞了多个信息的问题比如“张三-北京-销售部”需要拆成三列。选中这一列在“转换”选项卡里点“拆分列”→“按分隔符”输入-Power Query 会按分隔符切成三列自动命名为“姓名.1”“姓名.2”“姓名.3”。如果分隔符在数据里出现得很乱比如有的行可能没有第三个段拆出来的列数会不一致Power Query 会用null填在缺失的位置。拆分列还可以按文本长度、按大写字母转换位置等方式切但这些用得不多。真正需要留意的是拆分后的数据类型会被判定为文本哪怕拆分出来的是“20250330”这种日期序列它也是文本需要你再做一个“更改类型”的步骤。这种低级转换造成的性能浪费通常就是一看查询计划才发现的。合并列正好相反把多列拼成一列比如把“年份”“月份”合并成“账期”。界面操作是选中两列右键“合并列”选择分隔符。一个特别常见的坑是当你合并之后数值列会变成文本列。比如你有一个“数量”列和一个“单位”列合并成“数量单位”后后续如果还要对“数量”做数学运算你会发现求和结果不对甚至报错。这是因为合并操作把数值强转成了文本。所以合并列要谨慎选择范围或者合并后补一个“更改类型”恢复数值属性。拆分和合并的界面操作对应的 M 函数分别是Table.SplitColumn和Table.CombineColumns。比如按分隔符拆分的 M 代码长这样Table.SplitColumn( 源, 姓名与部门, Splitter.SplitTextByDelimiter(-, QuoteStyle.Csv), {姓名, 地区, 部门} )参数含义很直白第一参数是待处理的表第二参数是要拆的列名第三参数是拆分规则第四参数是拆分后的列名列表。QuoteStyle.Csv表示在 CSV 转义规则下识别分隔符如果你要拆的数据里分隔符本身可以作为内容出现比如“张三-北京-“销售-部””这个参数就很有用。4.2 合并查询和追加查询多表关联和数据堆叠是两个方向的操作有一点先要分清“合并查询”是把两个表的行关联起来类似 Excel 的 VLOOKUP但比 VLOOKUP 灵活它可以做左外、右外、内联、全外等多种连接“追加查询”是把两个结构相同的表上下堆在一起类似在所有数据末尾粘贴另一个表格。先说合并查询。操作路径“开始”→“合并查询”第一个对话框选主表第二个选关联表然后点选两个表中匹配的列最后选择连接种类。默认是“左外部”意思是保留主表所有行关联表里找不到匹配的行会用null填充。如果你要的是只留下匹配行就选“内部”。合并之后右侧关联表会整体变成一列列名是“NewColumn”之类的你需要点击这一列标题右侧的展开图标选择要带进来的字段然后确定。展开这一步非常容易翻车很多人选了“使用原始列名作为前缀”之后列名变得很长后续引用特别别扭。我一般都会取消勾选前缀让展开的列名简洁一些。合并产生的 M 公式核心是Table.NestedJoinTable.NestedJoin( 订单表, {客户ID}, 客户表, {客户ID}, 客户信息, JoinKind.LeftOuter )意思是以客户ID作为匹配键把两个表关联起来关联结果暂存在一个名为客户信息的嵌套列中。之后你还需要Table.ExpandTableColumn展开这个嵌套列里的字段这就是为什么合并后总是多一步展开操作。追加查询则简单得多。在“开始”→“追加查询”里选择“将查询追加为新查询”把需要堆叠的查询加入列表即可。注意追加查询只检查列名是否一致它不会帮你去重更不会补全缺失列。如果你想合并不同结构的多个表得先在每个表里用“删除其他列”保住共同列。这里有一个我这几年反复见到的坑合并查询时两个表的匹配列类型不一致。比如主表的“客户ID”是文本类型客户表的“客户ID”是整数类型合并结果里会大量出现null看起来就像数据丢失。这不是数真丢了而是类型不一致导致匹配失败。解决方案是合并前在两边都各自做一个“更改类型”把匹配列统一成同一种类型。排查方式也很简单看合并后展开的那列是否大面积 null如果有先去检查匹配列的类型。4.3 分组和透视在界面里完成原本要写复杂公式的活如果要对订单按省份汇总销售额传统做法是插个数据透视表或者写 SUMIFS 公式。但数据透视表每次刷新需要手动刷新数据源SUMIFS 则难以应对行数变化。Power Query 的分组功能相当于把这些聚合逻辑固化进了查询里。操作步骤在“转换”选项卡点“分组依据”第一栏选择分组列比如“省份”第二栏添加聚合操作选择“销售额求和”Power Query 会生成一个新表包含“省份”和“销售额求和”两列。你也可以一次添加多个聚合比如同时求销售额平均值、订单笔数、最大订单额等。分组对应的 M 公式是Table.Group( 订单表, {省份}, { {销售额合计, each List.Sum([销售额]), type number}, {订单笔数, each Table.RowCount(_), Int64.Type} } )这里each后面是聚合逻辑List.Sum([销售额])表示对当前分组内的销售额列求和Table.RowCount(_)表示统计当前分组内的行数type number和Int64.Type是结果的显式类型声明。把类型声明写全Power Query 在后续步骤中能少做很多类型推断性能也会更好。透视列是另一个高频操作。它把某列里不同的值变成列标题比如把“季度”列里的“Q1、Q2、Q3、Q4”变成四列每个单元格填对应数值。操作路径选中“季度”列“转换”→“透视列”再选一个值列作为单元格内容。透视之后表格行数会大幅减少但会出现很多null空值比如某个季度没有销售。这时要用“转换”→“替换值”把null替换成 0以免后续计算时报错。透视列的坑在于如果你透视时选错了值列或者值列里存在一对多的问题透视结果会变成一个多对多的矩阵列数爆炸。所以透视之前最好先确认“行”由哪些列唯一确定Q1 只有一行对应省份、产品这类维度才有意义。4.4 用“创建参考”替代复制查询保住一条可维护的链路前面提过一次复制和参考的区别这里再展开说复制是复制当前查询的全部步骤之后与源查询断开联系创建参考则是新建一个查询它的源是当前查询的输出结果源查询任何一步的调整都会传导到这个参考查询上。这有什么价值比如你有一条很长的清洗查询最终输出的是“订单明细_已清洗”。如果要在它基础上分别做“按月汇总”和“按产品汇总”你不必复制两份完整的清洗步骤只需右键这条查询选“创建参考”生成两个轻量查询各自再只做分组聚合。上游清洗逻辑一旦需要修改你只改一处两个参考查询自动跟着变维护成本大幅降低。但有个副作用要知道每次创建参考时Power Query 会复制一份数据到内存里。如果上游查询处理的是 100 万行而你创建了 5 个参考查询内存里就会同时存在 5 份 100 万行数据刷新时消耗会明显增加。所以参考查询适合下游轻量聚合不适合继续做重型清洗。真正的重型清洗应该只保留一条主干查询其余都从参考派生这是我在实际项目里优化刷新速度时最常用的一种结构。5. Power Query 常见问题排查5 个让新手翻车的现场和对策5.1 刷新结果不对但没有任何报错多半是数据类型悄悄变了现象查询刷新后没有报错但数字变成了一串看起来像“43831”的数值日期变成了天数序号或者金额列求和结果少了很多位小数。原因导入数据时Power Query 自动对列做了类型推断某些列被识别成了文本或日期后续做聚合时就会出现偏差又因为类型转换被当成“可见步骤”里的一个隐藏细节而没被注意到。解决在查询设置里加一步“更改的类型”把每列类型显式固定下来尤其是数字列、日期列和文本长度超过 15 位的文本列。记住Power Query 的类型推断只信第一行几十行数据不代表全列类型遇到混合内容必须手动指定类型。5.2 删除中间步骤后一连串步骤报错步骤链是有依赖的现象在“已应用步骤”里删除了某一步比如“删除的列”下方好几个步骤立刻出现红色感叹号。原因被删除的这一步产出的字段被后面的步骤引用着一旦上游字段消失下游步骤找不到输入。解决不要直接删除步骤改成修改步骤内容。比如你要做的事是“不删备注列”而是希望后面步骤不引用它正确的做法是保留删除步骤同时去修改后面引用逻辑比如把筛选条件里的字段改为其他列。如果非删不可务必先检查后面每一个步骤的公式栏看有没有引用被删字段。高级编辑器里搜一下字段名比肉眼检查更靠谱。5.3 合并查询结果大量为空白优先检查关联列类型和大小写现象合并两个表后展开关联结果时发现很多null但去看原始数据两个表明明有对应值。原因最常见的是关联列类型不一致一个是文本一个是整数导致匹配不上也有是关联列存在前后空格或大小写不一致。解决合并之前在两个源查询里各加一步“更改的类型”把关联列统一为同一种类型再用“转换”→“修整”清除首尾空格最后确认关联键格式一致。检查方法不复杂在合并对话框里选完关联列下方会显示“找到的匹配行数”如果匹配数远小于总行数八成就是类型或空格问题。5.4 从文件夹导入后新文件导致刷新失败结构一致性比文件数量更关键现象文件夹导入的查询原本好好的某天新增了一个文件后刷新报错提示“找不到列”或“无法转换类型”。原因Power Query 按示例文件定义的步骤套用到所有文件新文件某列名称变了、多了一列、或者某列数据类型不同步骤就会失败。解决在文件处理的函数开头用Table.SelectColumns固定需要的列集合再用Table.TransformColumnTypes统一类型这样即使新文件多出无关列也会被裁掉如果遇到列缺失需要先判断是否真的允许缺失允许时可以用Table.SelectColumns配合Table.ColumnNames做动态列名筛选。另外把新建的文件夹路径做成参数下次路径变了不用改函数体。5.5 查询刷新越来越慢三步定位慢在哪一步现象查询在开发时很快用了一周后越来越慢刷新一次要十几分钟。原因很多情况是因为查询把大量步骤放在读取后的早期阶段比如先做类型转换再做筛选或者合并查询在本地展开一个巨大的嵌套列。解决用“视图”→“查询依赖”查看整体结构然后右键每个步骤的“本机查询”检查是否可以下推优先把筛选和分组往前挪。还有一个技巧给查询设置一个“仅创建连接”的中间查询把重型清洗单独保留下游聚合基于创建参考而不是每个报表都独立重跑一遍相同清洗步骤。6. 把查询升级成可复用工具参数、自定义函数与一次刷新习惯最后一个进阶技巧我会做一件事把最常用的批量汇总做成“传参即用”的模板。具体思路是用 Excel 单元格作为参数输入面板Power Query 读取这些参数再通过自定义函数处理文件夹里的所有报表最后输出汇总结果。这样你下次换文件夹路径、改统计阈值时不用进 Power Query 编辑器直接改单元格刷新一下就行。先在工作表里选两个单元格用来输入参数比如把“C:\data\orders”写在某个固定单元格把用来筛选的最小金额阈值写在另一个单元格。然后新建一个空查询用Excel.CurrentWorkbook()读取参数表中的值let 参数表 Excel.CurrentWorkbook(){[Name参数表]}[Content], 文件路径 参数表{0}[文件路径列], 最小金额 参数表{0}[阈值列] in 文件路径再把之前写的处理函数扩展一下接收路径和阈值两个参数(文件路径 as text, 文件名 as text, 最小金额 as number) let 源 Excel.Workbook(File.Contents(文件路径 文件名), null, true), 订单表 源{[Item订单, KindTable]}[Data], 类型修正 Table.TransformColumnTypes(订单表, {{金额, type number}, {日期, type date}}), 筛选行 Table.SelectRows(类型修正, each [金额] 最小金额) in 筛选行最后在装配查询中调用这个函数时传入参数表中的值。之后每个月换新文件夹你只需要改那个参数单元格点一次“数据”→“全部刷新”整条链路就重新跑一遍。这个习惯帮我省下了大量重复性劳动也让团队里不会写 M 公式的同事也能用模板。这几年最深的教训是Power Query 的问题很少出在“不知道用什么按钮”而是出在“没搞清步骤间依赖关系、没固定数据类型、没提前考虑源结构变化”。把这一条主线记在心里遇到任何查询报错先看步骤链再看类型最后看源基本都能快速定位。希望这份入门手册能帮你在数据清洗这条路上少走几次弯路。本文还有配套的精品资源点击获取