从 SQL 到 Power BI:我用 4 个查询做出第一张销售分析报表
一个会写 SQL 但从没碰过 Power BI 的人,从零搭出一张可交付的销售分析报表,记录全过程和踩过的坑。
为什么做这个报表
我日常写 SQL Server,数据查得出来,但每次给业务方看结果,都要导出 Excel 再手动做表 —— 一次两次可以,长期就是体力活。最近把这套流程换成了 "SQL 查询 + Power BI 可视化",用微软经典的 AdventureWorks 练习库搭了一张销售月度分析报表。
这篇文章完整记录搭建过程,包括四个真实踩坑(每个都是 Power BI 新手必踩)。
数据与口径
数据源:本地 SQL Server 2025,自建 AdventureWorks2019 练习库(2023-01 至 2025-12,约 4400 张订单)。四个分析视角全部对齐 SQL 查询口径:
- 月度销售趋势:按月汇总销售额(含税运 TotalDue)与订单数
- 区域销售对比:6 个销售区域的销售额排名
- Top 10 客户:累计销售额最高的 10 个客户(个人客户显示姓名,企业客户显示店名)
- 产品类别占比:按明细 LineTotal 统计 Bikes / Components / Accessories / Clothing 占比
一个关键口径:所有分析只统计 Status = 5(已发货订单),在 Power BI 里用页面级筛选器实现,保证所有图表数字和 SQL 查询对得上。
搭建过程
1. SQL 端:4 个查询先跑通
先在 SSMS 里把 4 个查询写好跑通,这一步是根本 ——Power BI 只是把查出来的结果可视化,SQL 错了后面全错。
2. Power BI 导入与建模
Power BI 连接 localhost 的 AdventureWorks2019,导入 9 张表,确认关系:订单明细→订单头、产品→子类→类别、客户→个人 / 企业,等价于 SQL 里的 JOIN 条件。
3. 写 DAX 度量值
DAX 对会 SQL 的人非常友好,基本就是 "不用写 GROUP BY 的聚合":
销售额 = SUM('Sales SalesOrderHeader'[TotalDue])
订单数 = DISTINCTCOUNT('Sales SalesOrderHeader'[SalesOrderID])
客单价 = DIVIDE([销售额], [订单数])
客户名称是个计算列,本质就是 CASE WHEN:
客户名称 =
IF(
NOT ISBLANK('Sales Customer'[PersonID]),
RELATED('Person Person'[FirstName]) & " " & RELATED('Person Person'[LastName]),
IF(NOT ISBLANK('Sales Customer'[StoreID]), RELATED('Sales Store'[Name]), "未知")
)
4. 拖出 4 张图
折线图看趋势、条形图排区域、Top 10 条形图看重点客户、环形图看品类结构,一页 2×2 布局,业务方扫一眼就有结论。
四个必踩的坑(重点)
坑 1:表名带 schema 前缀,公式里写 "找不到表"
SQL Server 的表在 Sales / Person / Production 三个 schema 下,Power BI 导入后表名变成 Sales SalesOrderHeader(带空格)。DAX 里表名含空格必须用单引号包住:
-- 错的:找不到表
销售额 = SUM(SalesOrderHeader[TotalDue])
-- 对的
销售额 = SUM('Sales SalesOrderHeader'[TotalDue])
坑 2:文本列 X 轴排序乱
按月份做的 "年月" 列(FORMAT 成 "2023-02" 文本),拖到折线图 X 轴后顺序完全乱。Power BI 对文本轴排序不可靠,解法是加一个数值排序列:
年月序号 = YEAR('Sales SalesOrderHeader'[OrderDate]) * 100 + MONTH('Sales SalesOrderHeader'[OrderDate])
然后选中 "年月" 列 → 列工具 → 按列排序 → 选 "年月序号",时间顺序立刻正确。*100 是给月份留两位空间,本质是把 "2023" 和 "02" 拼成数字 202302。
坑 3:判断条件写错表
写客户名称公式时,我把判断写成了 'Sales Store'[StoreID]—— 但 Store 表根本没有 StoreID 这个字段(它的主键叫 BusinessEntityID)。正确逻辑是:判断永远看 Customer 表的 PersonID / StoreID,RELATED 只是沿关系去对方表取名字。
坑 4:导出 PDF 缩在左上角
画布设成 16:9 后,导出 PDF 还是一小块 —— 原因是导出对话框默认 "纵向",横版画面塞纵向纸只能缩在顶部。导出时方向改成 "横向" 就铺满了。
写在最后
整套流程跑通后,最直观的感受是:Power BI 没有新东西,它就是把你 SQL 里的 GROUP BY、WHERE、JOIN 换成了拖拽。会 SQL 的人学它,本质是补一层可视化思维,而不是重学一门语言。
如果你也在做 "SQL 结果报表化",或者有查询开发、报表搭建的需求,欢迎评论区交流;完整脚本和 .pbix 源文件我都整理好了,需要的可以留言。