跳到主要内容

Power Pivot数据建模

本章概览

Power Pivot是Excel的数据建模和分析增益集,能够处理百万行级别的数据,创建复杂的数据模型,并使用DAX语言进行高级计算。它是Excel向商业智能(BI)方向发展的重要工具。

学习目标

  • 掌握Power Pivot数据模型基础
  • 学会创建表关系和星型模型
  • 熟练使用DAX基础函数
  • 掌握度量值和计算列
  • 学会KPI和层次结构应用

前提条件 Excel 2013或更高版本(专业增强版/Microsoft 365)


27.1 Power Pivot入门

27.1.1 启用Power Pivot

检查是否可用

功能区是否有"Power Pivot"选项卡
如果没有,需要启用

启用方法

文件 → 选项 → 加载项
管理:COM加载项 → 转到
勾选"Microsoft Power Pivot for Excel"
确定

Power Pivot窗口

Power Pivot → 管理
打开Power Pivot数据模型窗口

组成:
- 表视图:查看和编辑数据
- 关系图视图:创建和管理表关系
- 计算区域:创建度量值

27.1.2 导入数据

从Excel导入

Power Pivot → 管理 → 从其他源
选择"Excel文件"

或:
先用Power Query导入和清洗
再加载到数据模型

从数据库导入

从其他源 → SQL Server/Access/Oracle
输入连接信息
选择表或视图

从Power Query导入

Power Query → 关闭并上载 → 关闭并上载到
勾选"仅创建连接"
勾选"将此数据添加到数据模型"

27.1.3 数据模型 vs 普通表

数据模型优势

1. 处理能力:
- 普通表:最多104.8万行
- 数据模型:数百万行

2. 关系:
- 普通表:VLOOKUP函数
- 数据模型:建立表关系

3. 计算:
- 普通表:公式
- 数据模型:DAX度量值

4. 存储:
- 普通表:明文存储
- 数据模型:列式压缩

27.2 创建表关系

27.2.1 关系类型

一对多关系(常用)

示例:
客户表(一) ←→ 订单表(多)
一个客户可以有多个订单

产品表(一) ←→ 订单明细(多)
一个产品可以在多个订单明细中出现

一对一关系

示例:
员工表 ←→ 员工详细信息表

多对多关系

Power Pivot不直接支持
需通过桥接表实现

示例:
学生 ←→ 选课记录 ←→ 课程

27.2.2 创建关系

方法一:拖放(关系图视图)

1. Power Pivot → 关系图视图
2. 拖动主表的主键到相关表的外键
3. 自动创建关系

示例:
拖动"客户表[客户ID]"到"订单表[客户ID]"

方法二:管理关系

设计 → 创建关系
1. 选择表1和列
2. 选择相关表2和相关列
3. 确定

示例:
表1: 订单表
列: 客户ID
相关表: 客户表
相关列: 客户ID

注意事项

- 主键列必须唯一(无重复)
- 数据类型必须相同
- 一个表只能有一个活动关系连接另一表
- 多个关系可存在,但只有一个激活

27.2.3 星型模型设计

概念

中心:事实表(Fact Table)
- 记录业务事件
- 包含度量值(销售额、数量等)
- 包含外键

外围:维度表(Dimension Table)
- 描述性信息
- 包含主键
- 提供筛选和分组

示例:销售数据模型

        维度表

┌─────────┐
│ 日期表 │
└────┬────┘

┌────↓────┬─────────┬─────────┐
│ │ │ │
┌───↓───┐ ┌──↓───┐ ┌──↓───┐ ┌──↓───┐
│产品表 │ │客户表│ │地区表│ │销售表│← 事实表
│ │ │ │ │ │ │(中心)│
└───────┘ └──────┘ └──────┘ └──────┘

关系设置

销售表[产品ID] → 产品表[产品ID]
销售表[客户ID] → 客户表[客户ID]
销售表[地区ID] → 地区表[地区ID]
销售表[日期] → 日期表[日期]

27.3 DAX基础

27.3.1 DAX简介

什么是DAX

Data Analysis Expressions
数据分析表达式

用途:
- 创建计算列
- 创建度量值
- 创建计算表

DAX vs Excel公式

相似:
- 使用函数
- 使用运算符(+、-、*、/)

不同:
- DAX引用整列或表
- DAX自动处理上下文
- DAX有专用聚合函数

27.3.2 基本语法

引用列

同表: [列名]
其他表: 表名[列名]

示例:
[销售额]
产品表[产品名称]

引用表

表名
示例:
RELATED(客户表[客户名称])

常量

数字: 100
文本: "北京"(双引号)
日期: DATE(2024,1,1)
布尔: TRUE / FALSE

运算符

算术: + - * / ^
比较: = < > <= >= <>
逻辑: && (AND) || (OR)
连接: & (文本连接)

27.3.3 计算列 vs 度量值

计算列

特点:
- 存储在表中
- 行级计算
- 占用内存
- 创建位置:表视图

创建:
在表下方空白行输入公式

示例:
总额 = [单价] * [数量]

度量值(推荐)

特点:
- 不存储,动态计算
- 聚合计算
- 节省内存
- 创建位置:计算区域

创建:
Power Pivot → 度量值 → 新建度量值

示例:
总销售额 = SUM([销售额])

选择建议

计算列:
- 需要在行级别计算
- 需要筛选、排序、分组

度量值:
- 聚合计算(求和、计数、平均值)
- 动态计算(随筛选条件变化)
- 大多数情况推荐使用

27.4 常用DAX函数

27.4.1 聚合函数

SUM/AVERAGE/MIN/MAX

总销售额 = SUM([销售额])
平均单价 = AVERAGE([单价])
最高价格 = MAX([单价])
最低价格 = MIN([单价])

COUNT/COUNTA/COUNTROWS

# COUNT: 计数数字
订单数 = COUNT([订单号])

# COUNTA: 计数非空
客户数 = COUNTA([客户名称])

# COUNTROWS: 计数行
总行数 = COUNTROWS(订单表)

DISTINCTCOUNT

# 计数唯一值
唯一客户数 = DISTINCTCOUNT([客户ID])
唯一产品数 = DISTINCTCOUNT([产品ID])

27.4.2 CALCULATE函数

语法

CALCULATE(表达式, 筛选器1, [筛选器2], ...)

基础用法

# 北京地区销售额
北京销售额 = CALCULATE(
SUM([销售额]),
地区表[地区] = "北京"
)

# 高价产品销售额
高价产品销售额 = CALCULATE(
SUM([销售额]),
产品表[单价] > 100
)

多条件筛选

# 北京地区的苹果销售额
= CALCULATE(
SUM([销售额]),
地区表[地区] = "北京",
产品表[产品名] = "苹果"
)

ALL函数移除筛选

# 总销售额(忽略所有筛选)
总销售额 = CALCULATE(
SUM([销售额]),
ALL(销售表)
)

# 占比计算
销售额占比 =
DIVIDE(
SUM([销售额]),
CALCULATE(SUM([销售额]), ALL(销售表))
)

27.4.3 时间智能函数

日期表要求

必须包含连续日期
必须标记为日期表(设计 → 标记为日期表)

TOTALYTD/TOTALQTD/TOTALMTD

# 年初至今销售额
年初至今销售 = TOTALYTD(
SUM([销售额]),
日期表[日期]
)

# 季初至今
季初至今销售 = TOTALQTD(SUM([销售额]), 日期表[日期])

# 月初至今
月初至今销售 = TOTALMTD(SUM([销售额]), 日期表[日期])

同比环比

# 去年同期销售额
去年销售额 = CALCULATE(
SUM([销售额]),
SAMEPERIODLASTYEAR(日期表[日期])
)

# 同比增长率
同比增长率 =
DIVIDE(
SUM([销售额]) - [去年销售额],
[去年销售额]
)

# 上月销售额
上月销售额 = CALCULATE(
SUM([销售额]),
PREVIOUSMONTH(日期表[日期])
)

# 环比增长率
环比增长率 =
DIVIDE(
SUM([销售额]) - [上月销售额],
[上月销售额]
)

DATEADD

# N天前/后
N天前销售 = CALCULATE(
SUM([销售额]),
DATEADD(日期表[日期], -7, DAY) # 7天前
)

# N月前/后
去年同月 = CALCULATE(
SUM([销售额]),
DATEADD(日期表[日期], -12, MONTH)
)

27.4.4 关系函数

RELATED

# 从相关表获取值(多方引用一方)
在订单表中创建计算列:
客户名称 = RELATED(客户表[客户名称])
产品类别 = RELATED(产品表[类别])

RELATEDTABLE

# 获取相关表的多行(一方引用多方)
在客户表中创建度量值:
客户订单数 = COUNTROWS(RELATEDTABLE(订单表))
客户总消费 = SUMX(RELATEDTABLE(订单表), [金额])

USERELATIONSHIP

# 激活非活动关系
# 当两表间有多个关系时使用

示例:订单表有"下单日期"和"发货日期"
都关联到日期表,但只有一个活动

发货金额 = CALCULATE(
SUM([金额]),
USERELATIONSHIP(订单表[发货日期], 日期表[日期])
)

27.4.5 迭代函数

SUMX/AVERAGEX

# 逐行计算后聚合
总金额 = SUMX(
订单明细,
[单价] * [数量]
)

平均订单金额 = AVERAGEX(
订单表,
[总金额]
)

FILTER

# 筛选表返回子集
高价产品销售 = SUMX(
FILTER(
产品表,
产品表[单价] > 100
),
[销售额]
)

# 复杂条件
= SUMX(
FILTER(
订单表,
订单表[金额] > 1000 && 订单表[地区] = "北京"
),
[金额]
)

27.5 数据透视表与Power Pivot

27.5.1 基于数据模型的数据透视表

创建

Power Pivot → 数据透视表
选择新工作表或现有工作表

字段列表

显示所有数据模型中的表
可拖动字段到:
- 筛选器
- 列
- 行
- 值

优势

1. 可使用多个表的字段
2. 关系自动处理
3. 可使用创建的度量值
4. 性能更好(百万行数据)

27.5.2 切片器

创建切片器

插入 → 切片器
选择维度表的字段

推荐:
- 日期(年、季、月)
- 地区
- 产品类别
- 客户类型

切片器交互

多个切片器自动联动
筛选同时影响所有数据透视表和图表

27.6 KPI和层次结构

27.6.1 KPI(关键绩效指标)

创建KPI

1. 创建基础度量值:
实际销售额 = SUM([销售额])

2. 创建目标度量值:
目标销售额 = SUM([目标])

3. 右键"实际销售额" → 创建KPI
4. 定义KPI目标 → 选择"目标销售额"
5. 定义状态阈值:
- <90%: 红色
- 90-100%: 黄色
- >100%: 绿色

在数据透视表中使用

字段列表 → 选择KPI字段
自动显示:
- 值
- 目标
- 状态(图标)

27.6.2 层次结构

创建层次结构

示例:时间层次
1. 右键"年" → 创建层次结构
2. 命名为"时间"
3. 右键层次结构 → 添加到层次结构 → 季度
4. 添加 → 月份
5. 添加 → 日期

结果:时间层次
└ 年
└ 季度
└ 月份
└ 日期

在数据透视表中使用

拖动层次结构到行
自动支持钻取:
点击+号展开下一级
点击-号折叠

常见层次

地理层次:
国家 → 省份 → 城市 → 区县

产品层次:
大类 → 中类 → 小类 → 产品

组织层次:
公司 → 部门 → 团队 → 员工

27.7 实战案例

案例1:销售分析数据模型

表结构

事实表:
- 销售表(订单号, 产品ID, 客户ID, 日期, 数量, 单价)

维度表:
- 产品表(产品ID, 产品名, 类别, 成本)
- 客户表(客户ID, 客户名, 地区, 类型)
- 日期表(日期, 年, 季度, 月, 周)

建立关系

销售表[产品ID] → 产品表[产品ID]
销售表[客户ID] → 客户表[客户ID]
销售表[日期] → 日期表[日期]

关键度量值

# 基础度量
销售额 = SUMX(销售表, [数量] * [单价])
销售数量 = SUM(销售表[数量])
订单数 = DISTINCTCOUNT(销售表[订单号])
客户数 = DISTINCTCOUNT(销售表[客户ID])

# 成本和利润
成本 = SUMX(
销售表,
[数量] * RELATED(产品表[成本])
)
毛利 = [销售额] - [成本]
毛利率 = DIVIDE([毛利], [销售额])

# 时间智能
年初至今销售 = TOTALYTD([销售额], 日期表[日期])
去年同期 = CALCULATE(
[销售额],
SAMEPERIODLASTYEAR(日期表[日期])
)
同比增长 = DIVIDE(
[销售额] - [去年同期],
[去年同期]
)

# 占比分析
销售额占比 = DIVIDE(
[销售额],
CALCULATE([销售额], ALL(产品表))
)

案例2:库存周转分析

额外表

库存表(产品ID, 日期, 期末库存)

度量值

# 平均库存
平均库存 = AVERAGE(库存表[期末库存])

# 库存周转率
库存周转率 = DIVIDE(
[销售成本],
[平均库存]
)

# 库存周转天数
周转天数 = DIVIDE(
365,
[库存周转率]
)

# 缺货天数
缺货天数 = CALCULATE(
COUNTROWS(库存表),
库存表[期末库存] = 0
)

27.8 最佳实践

27.8.1 数据模型设计

星型模型优先

√ 一个事实表,多个维度表
× 雪花模型(维度表再关联)
× 多个事实表直接关联

维度表设计

√ 主键唯一
√ 包含描述性字段
√ 相对稳定(不常变化)
√ 去除冗余字段

事实表设计

√ 包含度量值(数量、金额等)
√ 包含外键连接维度
√ 粒度一致
× 不存储可计算的值

27.8.2 DAX优化

度量值优先于计算列

# 不推荐(计算列)
总额 = [单价] * [数量]

# 推荐(度量值)
总额 = SUMX(表, [单价] * [数量])

使用变量

# 不推荐(重复计算)
毛利率 =
DIVIDE(
SUM([销售额]) - SUM([成本]),
SUM([销售额])
)

# 推荐(使用变量)
毛利率 =
VAR 销售额 = SUM([销售额])
VAR 成本 = SUM([成本])
RETURN
DIVIDE(销售额 - 成本, 销售额)

避免复杂嵌套

# 复杂度量值拆分为多个简单度量值
# 再组合使用

本章小结

核心要点

  1. Power Pivot:处理百万行数据的BI工具
  2. 数据模型:建立表关系,星型模型
  3. DAX语言:计算列和度量值
  4. 常用函数:聚合、CALCULATE、时间智能
  5. KPI和层次:监控指标和钻取分析

Power Pivot vs 数据透视表

功能数据透视表Power Pivot
数据量<100万行数百万行
多表关系不支持支持
高级计算有限DAX强大
性能一般优秀
学习曲线中高

学习建议

  1. 先掌握Excel公式和数据透视表基础
  2. 理解数据库基本概念(表、关系)
  3. 从简单DAX函数开始学习
  4. 多做实际案例练习
  5. 参考官方DAX函数文档

下一步学习

  • 第28章:Excel VBA编程基础
  • 第29章:Excel与Python集成
  • 第30章:Excel自动化办公

思考练习

  1. 创建一个销售数据模型,包含产品、客户、日期维度
  2. 建立表关系,设计星型模型
  3. 创建度量值计算销售额、毛利、毛利率
  4. 使用时间智能函数计算同比、环比
  5. 制作包含KPI的仪表盘

练习提示

  • 先设计模型结构再导入数据
  • 确保关系正确建立
  • 测试度量值计算是否准确
  • 使用数据透视表验证结果