📚 本文配套课程 · SQL 系列
🎬 B 站课程:DAX「别裁新解」 — https://www.bilibili.com/cheese/play/ss8780
- 如何选择BI工具:Power BI“向左”,Tableau“向右” 2023/02
- BI双雄:Power BI 向左,Tableau 向右 2025/08
- SQL 向左,DAX 向右:数据库范式与分析范式的思维碰撞(简化) 2025/10
“SQL 向左,DAX 向右”这一比喻,不仅是分析语言的选择,更象征着分析思维范式的根本性分野。本次研究旨在深入探讨这两种路径的本质差异,并以两部关于数据分析表达式(DAX)的重要著作为分析棱镜,揭示其背后的认知模型、逻辑单元与数据环境的深刻对立。
SQL 向左,代表了数据架构师与工程师的世界。这是一个静态的、请求-响应式的模型,其核心目标是从一个结构清晰、高度规范化的数据库中,通过显性、过程化的指令,提取一个确切无疑的、结构化的结果集 1。其思维根植于数据的构建、存储与完整性,强调的是对数据“是什么”的精确定义与提取。
DAX 向右,则通往业务转译者与分析工程师的领域。它在一个动态的、交互式的环境中运作,其目标并非生成单一的答案,而是构建一个灵活的分析模型——一个语义层(Semantic Layer),能够根据用户不断变化的上下文,回答成百上千个潜在的业务问题 1。其思维核心在于业务逻辑的封装与动态响应,强调的是对业务“为什么”的探索与洞察。
为了导航这一分野,本报告将引入两部关键指南:
- 《The Definitive Guide to DAX (2nd Edition)》,由 Marco Russo 和 Alberto Ferrari 合著,被誉为 DAX 领域的“圣经”。本报告将视其为“原住民指南”,它从第一性原理出发,要求学习者彻底摒弃旧有思维,以 DAX 的原生逻辑重构认知 4。
- 《DAX 别裁新解》手稿,由喜乐君撰写,是一部探索性的诠释之作。本报告将视其为“比较语言学指南”,它通过将 DAX 与 SQL、Tableau 进行对比,试图建立一个全新的概念框架,从而凸显 DAX 在整个分析生态中的独特定位 5。
通过对这两部著作的深度解读与综合分析,本报告将系统性地阐明“SQL 向左,DAX 向右”这一范式分野的内在逻辑与深远影响。
引言:两个世界的故事——OLTP 与 OLAP 的分野
在数据技术的广阔领域中,存在着两个平行而又紧密相连的世界,它们各自遵循着不同的法则,服务于截然不同的目标。这两个世界分别是在线事务处理 (Online Transaction Processing, OLTP) 和在线分析处理 (Online Analytical Processing, OLAP) 1。理解这两个世界的分野,是 comprehending SQL 与 DAX 之间深层次差异的逻辑起点。这并非简单的语言语法对比,而是一场源于系统设计哲学的思维范式碰撞。OLTP 系统的核心使命是高效、准确地支撑企业的日常运营——即“运营业务” (run the business);而 OLAP 系统的核心使命则是从海量历史数据中提炼洞察,辅助战略决策——即“理解业务” (understand their business) 1。
OLTP 系统是现代商业运作的心脏,它为支付处理、订单录入、客户关系管理等高频次、实时性的业务场景而生 1。其架构设计的首要目标是优化数据写入操作,确保每一笔交易都能被快速、原子性地记录,同时维护严格的数据一致性和完整性 4。为此,OLTP 系统通常采用高度规范化的关系型数据模型,将数据拆分到多个表中,以最大限度地减少数据冗余 2。其性能衡量标准是毫秒级的响应时间,以支持成千上万的并发用户操作 1。
与此相对,OLAP 系统是企业决策的大脑,专为复杂的分析查询、趋势预测和多维度数据探索而设计 3。其架构完全为数据读取密集型工作负载而优化,能够高效地聚合和分析来自多个数据源(通常包括 OLTP 系统)的海量历史数据 2。为了加速查询,OLAP 系统倾向于采用多维数据模型(如数据立方体)或反规范化的数据结构(如星型或雪花型模式),通过预先聚合和宽表设计来减少查询时所需的复杂连接操作 2。其性能衡量标准通常是秒级甚至分钟级的响应,以应对需要扫描数百万乃至数十亿行数据的深度分析任务 1。

这种源于目标冲突的架构分离是一种必然的工程选择。一个系统无法同时为高并发的原子写入(OLTP 的要求)和大规模的复杂读取(OLAP 的要求)进行优化。OLTP 数据库的行级锁定和高度规范化设计虽然保证了事务的完整性,但对于分析查询却是性能的噩梦;反之,OLAP 的列式存储和反规范化结构虽能极大提升分析速度,却不适合高频次的单行数据更新 5。因此,OLTP 与 OLAP 的分离,以及从前者到后者的数据流动(通常通过提取-转换-加载,即 ETL 过程实现),构成了传统数据架构的基石 2。
正是这一根本性的分野,催生了两种截然不同的数据语言和思维模式。SQL (Structured Query Language),作为关系型数据库的通用语言,其设计哲学、语法结构和最佳实践,无不深刻地烙印着 OLTP 世界对秩序、完整性和事务性的追求。而 DAX (Data Analysis Expressions),作为现代内存分析引擎的原生语言,则完全是为了满足 OLAP 世界对交互性、动态计算和业务建模的灵活需求而生。因此,从 SQL 到 DAX 的旅程,远不止是学习一套新的语法,更是从一个严谨的、以数据存储为中心的“数据库范式”,迁移到一个灵活的、以业务问题为中心的“分析范式”的过程。
| 标准 | 在线事务处理 (OLTP) | 在线分析处理 (OLAP) |
| 目的 | 管理和处理实时业务交易,支撑日常运营 3。 | 分析海量历史数据,支持战略决策和趋势洞察 2。 |
| 数据源 | 通常是单一的、实时的业务系统数据 4。 | 来自多个数据源(包括 OLTP 系统)的历史和聚合数据 3。 |
| 数据结构 | 关系型数据库,采用行式存储 4。 | 多维模型(数据立方体)或关系型数据库,采用列式存储 4。 |
| 数据模型 | 高度规范化(如第三范式),旨在减少数据冗余 2。 | 反规范化(星型/雪花型模式),旨在优化查询性能 2。 |
| 数据量 | 相对较小,通常为 GB 级别 4。 | 巨大,通常为 TB 甚至 PB 级别 1。 |
| 响应时间 | 极快,毫秒级 1。 | 较慢,秒级到分钟级 1。 |
| 核心操作 | 高频次的写入、更新、删除(INSERT, UPDATE, DELETE) 4。 | 读取密集型,复杂的聚合查询(SELECT with GROUP BY) 2。 |
| 用户群体 | 一线员工、客户、应用程序(如银行柜员、网店系统) 1。 | 数据分析师、业务经理、决策者 1。 |
| 应用示例 | 订单处理、在线预订、银行交易、库存管理 1。 | 销售趋势分析、财务报表、市场营销活动效果评估 2。 |

第一部分:SQL 的世界 —— 关系范式的基
SQL 所代表的世界,是一个建立在数学逻辑和严格秩序之上的领域。它的诞生和发展,与关系模型的理论奠基、数据库范式化的工程实践以及面向事务的系统架构紧密相连。要理解 SQL 的思维模式,就必须回溯其根源,探究其为解决 OLTP 场景下数据一致性与完整性问题而形成的一整套设计哲学。
1.1 历史的回响:从科德关系模型到 System R
SQL 的血脉可以追溯到 1969 年至 1970 年,当时任职于 IBM 的英国计算机科学家埃德加·科德 (Edgar F. Codd) 发表了开创性的论文,首次提出了关系数据模型 (Relational Model) 6。这一模型的革命性在于,它主张用一种与一阶谓词逻辑相一致的结构和语言来管理数据 6。在关系模型中,所有数据都被表示为元组(Tuples),并组织在关系(Relations)之中,这在实践中演变成了我们今天所熟知的行和表 7。
科德模型的根本目的,是提供一种“声明式”的方法来指定数据和查询 6。用户只需直接陈述数据库包含什么信息以及他们想从中获取什么信息,而将如何组织数据结构和设计检索过程的复杂任务交给数据库管理系统(DBMS)软件本身 6。这一理念极大地简化了数据操作,将用户从繁琐的底层数据导航中解放出来。
为了验证并实现科德的理论,IBM 圣何塞研究实验室于 1974 年启动了一个名为 System R 的研究项目 8。System R 项目具有里程碑式的意义,因为它不仅是关系模型的首次重要实现,更是 SQL 语言的诞生地 8。项目团队开发了一种名为 SEQUEL (Structured English Query Language) 的语言,后来演变为 SQL。System R 项目首次证明了关系型数据库系统不仅在理论上是优雅的,在实践中也能提供优秀的事务处理性能,其设计决策和核心算法(如查询优化中使用的动态规划算法)对后来的所有关系型系统产生了深远的影响 8。
1.2 秩序的艺术:数据库范式化精解
数据库范式化 (Database Normalization) 是关系模型理论在数据库设计中的核心实践,其根本目标在于通过组织表的结构来消除数据冗余和不一致的依赖,从而保护数据完整性 9。对于以数据一致性为首要目标的 OLTP 系统而言,范式化不仅是最佳实践,更是其哲学思想的体现。它通过一系列被称为“范式 (Normal Forms)”的规则,系统性地分解表,确保每一份非键信息都只存储在唯一一个地方 10。
- 第一范式 (1NF): 这是最基础的范式。它规定了数据库表的每一列都必须是“原子性”的,即不可再分 11。例如,一个“地址”列不能同时包含街道、城市和邮编;它们必须被拆分成独立的列。此外,1NF 要求表中不能有重复的行,并且必须有一个主键来唯一标识每一行 9。这个规则强制数据以二维表的结构进行组织,消除了非结构化的重复组 9。
- 第二范式 (2NF): 2NF 建立在 1NF 的基础之上,主要处理与复合主键相关的数据冗余问题。它要求表中的所有非键列都必须完全依赖于整个主键,而不是主键的一部分 11。这种依赖关系被称为“完全函数依赖”,违反此规则的情况称为“部分依赖”。例如,在一个包含(订单ID, 产品ID)作为复合主键的订单详情表中,如果“产品名称”列也存在于此,那么它就只依赖于“产品ID”,而与“订单ID”无关。为满足 2NF,需要将“产品名称”移至一个单独的、以“产品ID”为主键的产品表中 11。
- 第三范式 (3NF): 3NF 在 2NF 的基础上更进一步,旨在消除“传递依赖” 11。传递依赖指的是非键列依赖于另一个非键列,而不是直接依赖于主键。例如,在一个员工表中,主键是“员工ID”,表中包含“部门ID”和“部门名称”两列。这里,“部门名称”依赖于“部门ID”,而“部门ID”依赖于主key“员工ID”。这就构成了传递依赖。为满足 3NF,需要将“部门名称”移至一个单独的、以“部门ID”为主键的部门表中 9。3NF 通常被认为是大多数 OLTP 数据库设计的黄金标准,因为它在数据完整性和性能之间取得了良好的平衡。

通过范式化,OLTP 系统确保了数据操作的原子性和一致性。当需要更新一条信息时(例如客户地址),只需在一个地方修改,避免了在多个副本之间产生数据不一致的风险。然而,这种设计的代价是查询时需要进行更多的表连接(JOIN)操作,这恰恰是 OLAP 场景所要极力避免的。
1.3 语言的本质:SQL 的声明式哲学与结构
SQL 的核心是一种声明式语言,其设计理念是让用户专注于描述“想要什么(What)”,而非“如何实现(How)” 7。当用户提交一条 SELECT 查询时,他们定义了所需数据的来源、筛选条件和聚合方式,但并不指定数据库应使用何种索引、采用何种连接算法或具体的执行步骤。这些“如何做”的决策由数据库的查询优化器根据表的统计信息、索引结构等因素智能地决定 13。
尽管 SQL 在理论上是声明式的,但在实践中,一个优秀的 SQL 开发者为了追求极致性能,往往需要具备“指令式”的思维。他们会通过调整查询的写法(如使用子查询、公用表表达式 CTEs 或特定的连接顺序)来“暗示”或“引导”查询优化器生成更高效的执行计划 14。这种对底层执行机制的深刻理解,恰恰反映了 SQL 专家在看似声明式的语言背后,依然在与一个复杂的、指令式的执行引擎进行博弈。
SQL 语言的命令体系可以被清晰地划分为几个子集,每个子集都服务于不同的数据库管理功能 16:
- 数据定义语言 (DDL): 用于定义和管理数据库的结构。核心命令包括
CREATE(创建表、视图、索引等)、ALTER(修改表结构)、DROP(删除对象) 和TRUNCATE(清空表数据) 16。DDL 操作直接改变数据库的元数据。 - 数据操作语言 (DML): 用于操作存储在表中的数据。核心命令包括
INSERT(插入数据)、UPDATE(更新数据) 和DELETE(删除数据) 16。这些是 OLTP 系统中最频繁执行的操作。 - 数据控制语言 (DCL): 用于管理数据库的访问权限。核心命令是
GRANT(授予权限) 和REVOKE(撤销权限),它们是数据库安全体系的基石 16。

此外,SQL 提供了强大的抽象机制,如视图 (Views) 和存储过程 (Stored Procedures),用于封装复杂逻辑、简化应用开发和增强安全性 18。视图是一个基于 SELECT 查询结果的虚拟表,它可以隐藏底层表的复杂连接和列选择,向用户提供一个简化的数据接口 18。存储过程则是一组预编译的 SQL 语句集合,可以接受参数并执行复杂的业务逻辑,将计算任务从应用层下沉到数据库层,从而减少网络流量并提高性能 18。
1.4 架构的基座:面向事务的行式存储
传统的关系型数据库,尤其是为 OLTP 场景优化的系统,其物理存储架构是“行优化”的,即采用行式存储 (Row-Based Storage) 5。在这种模式下,一张表中某一行(一条记录)的所有列数据在磁盘上是连续存储的 5。例如,一条包含员工 ID、姓名、部门和薪水的记录,这四个字段的值会被紧挨着存放在一起。
这种存储方式对于事务性操作极为高效。当需要插入一条新记录 (INSERT)、更新一条现有记录 (UPDATE) 或删除一条记录 (DELETE) 时,数据库引擎可以一次性地定位到该行所在的物理位置,并在一个或少数几个 I/O 操作中完成对整行数据的读写 5。这与 OLTP 系统高频次、小批量的数据修改特性完美契合。然而,当面对需要聚合某一列(例如,计算所有员工的总薪水)的分析查询时,行式存储的劣势便暴露无遗:数据库必须读取每一行的全部数据,即使它只需要“薪水”这一列的信息,从而导致大量的无效 I/O 操作。这一架构上的根本特征,为后来面向分析的列式存储引擎的崛起埋下了伏笔。
第二部分:DAX 的世界 —— 分析范式的引擎
与 SQL 植根于严谨的关系理论和事务处理需求不同,DAX 的世界源于一个更为务实的目标:将强大的商业智能分析能力交到业务用户手中。它的诞生、其背后的 VertiPaq 引擎架构,以及它所推崇的维度建模,共同构成了一个专为 OLAP 场景设计的、以速度、灵活性和业务语义为核心的分析范式。
进入 21 世纪,随着数据量的爆炸式增长,传统的商业智能(BI)流程逐渐暴露出其固有的弊端。在 2000 年代中期,业务用户若想进行深度数据分析,通常需要向 IT 部门提交需求。IT 部门接着会启动一个漫长的流程:数据提取、转换、加载(ETL),并构建复杂的多维在线分析处理(OLAP)立方体(Cube)。这个过程不仅耗时数周甚至数月,而且产出的立方体一旦建成,其维度和度量值往往是固化的,难以灵活应对业务人员层出不穷的新问题。这种模式造成了分析师与数据之间的巨大鸿沟,严重制约了企业的决策效率和商业敏捷性。
微软敏锐地洞察到了这一市场痛点。业务用户,尤其是数以亿计的 Excel 用户,渴望一种能够摆脱 IT 依赖、实现数据分析自主性的工具。正是在这种背景下,微软内部一个代号为“双子座计划”(Project Gemini)的项目应运而生 。该项目由 SQL Server Reporting Services 团队的 Amir Netz 领导,其宏伟目标是将 SQL Server Analysis Services (SSAS) 的强大分析能力,从昂贵、复杂的服务器端,直接嵌入到用户最熟悉的前端工具——Microsoft Excel 中 。这个计划的核心,是实现“自助式商业智能”(Self-Service BI),让业务人员自己动手,快速地从数据中发现洞见。
2.1 “双子星”计划的遗产:Power Pivot 与 DAX 的诞生
DAX 的故事始于 2006 年微软内部一个代号为“双子星 (Project Gemini)”的计划 20。该计划由 SQL Server 报表服务团队的 Amir Netz 领导,其宏伟目标是将 SQL Server Analysis Services (SSAS) 的强大分析引擎能力,从企业级服务器的象牙塔中解放出来,直接嵌入到广大业务用户最熟悉的工具——Excel 中 20。这标志着“自助式商业智能 (Self-Service BI)”理念的萌芽,旨在让业务人员能够独立地从多个数据源收集数据、建立关联,并创建个性化的分析报告 21。
2009 年,作为该计划的成果,数据分析表达式 (Data Analysis Expressions, DAX) 语言正式发布 22。DAX 被设计为一种公式和查询语言,它借鉴了 Excel 公式的简洁易懂,同时融合了微软为 SSAS 多维模型开发的 MDX (Multidimensional Expressions) 语言的强大分析能力 22。
次年,即 2010 年 5 月,第一个搭载 DAX 的产品 PowerPivot 作为 SQL Server 2008 R2 的一部分正式面世 20。它以 Excel 加载项的形式存在,允许用户在 Excel 工作簿内创建包含数百万行数据的复杂数据模型,并使用 DAX 编写计算 21。PowerPivot 的出现,彻底改变了个人 BI 的游戏规则。随着时间的推移,这项技术不断演进,最终成为 Power BI Desktop 的核心引擎和“Excel 数据模型”的代名词,DAX 也随之成为微软整个 BI 技术栈的统一分析语言 20。

2.2 PowerPivot:新范式的新引擎
“双子座计划”的结晶,是在 2010 年作为 SQL Server 2008 R2 的一部分发布的 PowerPivot for Excel 。PowerPivot 并非一个简单的 Excel 功能增强,而是一场彻底的革命。它以一个 Excel 加载项的形式,为用户带来了一个前所未有的强大引擎,这个引擎后来被称为 VertiPaq(或 xVelocity)。
PowerPivot 的出现打破了多项传统限制 :
- 突破数据量限制: 传统的 Excel 工作表有约 100 万行的限制,而 PowerPivot 借助其内存引擎,可以轻松处理数百万甚至上千万行的数据。
- 实现关系建模: 用户可以在 PowerPivot 窗口中导入多个数据表,并像在数据库中一样,通过拖拽的方式建立表间关系,构建一个真正的关系数据模型。
- 高性能内存计算: 所有数据被加载到内存中,并以高度压缩的列式格式存储,使得聚合和计算速度极快,用户可以在瞬间完成对海量数据的切片、切块和钻取。
PowerPivot 的发布,标志着微软自助式 BI 平台的诞生。它将企业级的分析能力“民主化”,交到了最懂业务的分析师手中,让他们能够在自己熟悉的 Excel 环境中,完成以往只有 BI 专家才能完成的数据建模和分析工作。
2.3 DAX:为分析建模而生的混合语言
有了强大的引擎和数据模型,还需要一种与之匹配的语言来定义计算逻辑。为此,微软随 PowerPivot 一同发布了数据分析表达式(Data Analysis Expressions),即 DAX 。DAX 的设计哲学充分体现了其“自助式”的定位,它巧妙地融合了两种截然不同的语言基因,以降低学习曲线并提供强大的分析能力。
- 源自 Excel 公式的基因: DAX 的语法在表面上与 Excel 公式极为相似。它是一种函数式语言,通过函数的嵌套和组合来构建复杂的表达式 。
SUM,AVERAGE,IF等基础函数对于任何有经验的 Excel 用户来说都倍感亲切。这种设计极大地降低了业务用户的入门门槛,让他们可以将在 Excel 中积累的知识平滑地迁移到 DAT 中。 - 源自 MDX 的基因: 在简单的外表之下,DAX 继承了其前身——多维表达式(Multidimensional Expressions, MDX)——的核心分析思想 。MDX 是用于查询传统 OLAP 立方体的语言,其精髓在于对“上下文”(Context)的理解和操作。DAX 借鉴并简化了这一概念,使其适用于更易于理解的表格模型。DAX 中所有的计算都不是在真空中进行的,而是在一个由报表交互(如筛选器、切片器)动态决定的“评估上下文”中执行。这使得 DAX 能够实现 SQL 难以轻松完成的动态、上下文相关的分析,例如同比、环比、移动平均等。
DAX 的设计哲学是用户中心主义的典范。它刻意屏蔽了数据库管理的复杂性——这里没有 DDL 来定义表结构,没有 DML 来修改数据状态,也没有 TCL 来管理事务。所有的数据准备工作被假定已在 Power Query (M 语言) 或上游数据库中完成。DAX 的全部焦点都集中在“计算”上。它提供给用户的,是一个纯粹的、面向分析的函数式语言,感觉就像是 Excel 公式的超级进化版。正是这一精准的定位和设计,成功地为广大业务分析师打开了通往高级数据分析的大门,真正引爆了自助式 BI 的革命。
2.4 速度的引擎:VertiPaq 列式存储与内存计算
DAX 惊人性能的背后,是名为 VertiPaq(后更名为 xVelocity)的内存分析引擎 25。VertiPaq 的核心架构与传统 OLTP 数据库截然不同,它是一个内存中的 (in-memory) 列式数据库 (columnar database) 25。
列式存储 (Columnar Storage) 是 VertiPaq 性能的关键。与将一行所有数据连续存储的行式数据库相反,列式数据库将一列的所有数据连续存储在一起 26。这种架构为分析查询带来了两大革命性优势:
- 极致的数据压缩: 在一个数据列中,值的重复度通常非常高(例如,“国家”列可能只有几十个唯一值,却在数百万行中重复出现)。列式存储使得 VertiPaq 可以应用高效的压缩算法,极大地减小数据模型在内存中的体积,通常能达到 10 倍甚至更高的压缩率 26。
- 高效的聚合查询: 分析查询往往只关心少数几列的数据(例如,
SUM(销售额))。在列式存储中,引擎只需读取“销售额”这一列的数据,完全忽略其他不相关的列,从而极大地减少了 I/O 操作和内存扫描量,使得聚合计算速度飞快 26。
为了实现极致压缩,VertiPaq 综合运用了多种技术 26:
- 字典编码 (Dictionary/Hash Encoding): 这是最核心的压缩技术。引擎会为列中的每一个唯一值创建一个字典,并用一个非常小的整数(指针)来代替原始值。例如,一列文本数据可能被转换成一列整数,极大地减小了存储空间 26。
- 值编码 (Value Encoding): 针对整数列,引擎会找出该列的最小值,然后存储每个值与这个最小值的差值。这样,原本需要很多位来存储的大整数,就可以用较少的位来存储 26。
- 游程编码 (Run-Length Encoding, RLE): 当排过序的数据中出现连续重复的值时,RLE 会将这些重复值存储为“一个值 + 它连续出现的次数”,从而进一步压缩数据 26。

VertiPaq 引擎与维度建模的结合,是分析范式成功的关键。星型模式中长而窄的事实表,其包含大量重复外键和稀疏度量值的结构,恰好是列式引擎发挥其压缩和聚合优势的理想场景。反之,如果将一个高度规范化的 OLTP 模型直接载入 VertiPaq,其性能将大打折扣,因为引擎需要处理大量复杂的表间关系,这并非其设计之长。
2.5 模型的灵魂:维度建模与星型模式
如果说 VertiPaq 引擎是分析范式的“心脏”,那么维度建模 (Dimensional Modeling) 就是其“灵魂”。与数据库范式化追求消除冗余的目标相反,维度建模以业务用户的理解和查询性能为最高优先级,刻意采用反规范化的结构 2。
最经典的维度模型是星型模式 (Star Schema) 5。其结构直观清晰,由两类表组成:
- 事实表 (Fact Table): 位于星型模式的中心,存储着业务过程产生的度量值(Measures),这些值通常是数字且可累加的,如销售金额、订单数量、成本等。事实表还包含指向各个维度表的外键。事实表的特点是“窄而长”,即列数较少,但行数巨大,可能包含数十亿行记录 5。
- 维度表 (Dimension Tables): 围绕在事实表周围,像星星一样,存储着业务实体的描述性属性(Attributes),如产品信息(名称、分类、品牌)、客户信息(姓名、地区、等级)、时间信息(年、季、月、日)等。维度表为分析提供了上下文,是用户进行“切片和切块 (slice and dice)”操作的依据。维度表的特点是“宽而短”,即列数较多,但行数相对较少 5。

这种模型结构极大地简化了分析查询。用户几乎所有的查询都只需通过事实表与一个或多个维度表的简单连接即可完成,避免了在规范化模型中常见的多层、复杂的连接,从而显著提升了查询性能和模型的易用性 5。
2.4 核心的挑战:理解评估上下文
DAX 语言最强大也最令人困惑的核心概念,是评估上下文 (Evaluation Context) 29。它定义了 DAX 公式在计算时所处的“环境”,同一个公式在不同的上下文中会产生不同的结果 30。对于习惯了 SQL 静态、确定性查询环境的开发者来说,理解并掌握动态变化的评估上下文,是通往 DAX 精通之路的最大挑战 31。评估上下文主要由两部分组成:
- 筛选上下文 (Filter Context): 这是在公式开始计算之前,已经作用于数据模型上的一组筛选器 32。这些筛选器可以来自报告中的切片器、视觉对象(如矩阵的行、列标题)、页面/报告级筛选器,甚至是其他 DAX 公式 30。筛选上下文决定了公式在计算时能够“看到”哪些数据行。它类似于 SQL 查询中
WHERE子句和GROUP BY子句的组合效果,但其本质是动态的、由用户交互或公式逻辑实时构建的 32。 - 行上下文 (Row Context): 行上下文是“当前行”的概念 32。当 DAX 引擎需要逐行迭代一张表进行计算时,就会创建行上下文。最常见的两种情况是:1) 在计算列中,公式会为表的每一行计算一次,每一行都有自己的行上下文;2) 在迭代函数(如
SUMX,AVERAGEX,FILTER等)内部,函数会遍历其第一个参数(一张表),并为正在处理的每一行创建一个行上下文 30。在行上下文中,可以直接引用当前行的列值,例如[单价] * [数量]。

一个至关重要的机制是上下文转换 (Context Transition)。当在一个已存在行上下文的环境中调用一个度量值或使用 CALCULATE 函数时,DAX 引擎会将当前的行上下文“转换”为一个等效的筛选上下文 34。这个新的筛选上下文只包含当前行,从而使得度量值可以在单行的粒度上被正确计算。
DAX 的本质,可以说是一种用于查询和操纵评估上下文的语言。其核心函数,如 CALCULATE、FILTER、ALL、VALUES 等,其主要作用并非简单的数值计算,而是对筛选上下文进行修改——添加新的筛选器、移除已有的筛选器、或者改变表关系的行为。因此,学习 DAX 的过程,实际上是从学习函数语法,到理解如何运用这些函数来精确控制计算环境的思维转变过程。这正是它与 SQL 静态集合思维的根本区别所在。
2.5 认知模型:声明式集合 vs. 函数式上下文
- SQL(向左):其本质是一种声明式语言。
开发者只需声明“想要什么”数据,而由数据库引擎决定“如何获取” 2。一条 SQL 查询是一套自包含的指令,它作用于整个数据库,旨在生成一个静态的、可预测的结果集 1。其上下文在查询内部一次性定义(通过WHERE,GROUP BY等子句),查询的执行是独立的、请求-响应式的。
- DAX(向右):其本质是一种函数式语言,其中每一个表达式都是一个函数调用 2。
DAX 表达式的求值依赖于一个动态的评估上下文(Evaluation Context),而这个上下文绝大部分是由公式外部的环境(如报表视觉对象、切片器等)决定的 3。同一个度量值,在同一个视觉对象的不同单元格中,会因为上下文的改变而返回不同的结果。
范式综合:这一差异是两者最根本的区别。《The Definitive Guide to DAX》用其整个前半部分,系统地阐述了这种上下文驱动行为的底层机制 4。而《DAX 别裁新解》则为其提供了更易于理解的 conceptual scaffolding,称之为“计算阶段”和“问题详细级别” 5。一个广为流传的比喻精准地捕捉了这一差异:“在 SQL 中,你先把蛋糕烤好,然后再切片。而在 DAX 中,你在烤箱里切蛋糕” 1。SQL 的结果是预先固化的,而 DAX 的计算则是在最终呈现的瞬间,根据“切片”(即上下文)动态完成的。
第三部分:思维的碰撞 —— 从 SQL 到 DAX 的范式迁移
从 SQL 的世界迁移到 DAX 的世界,开发者所面临的不仅仅是语法的学习,更是一场深刻的思维范式变革。这种变革源于两种语言所服务的系统在交互模型、计算逻辑和数据关系处理上的根本差异。对于习惯了 SQL 严谨、确定性世界的专家而言,DAX 的动态、上下文驱动的特性往往会带来一系列的认知挑战和常见陷阱。
3.1 静态请求 vs. 动态交互
SQL 的工作模式是典型的请求-响应 (Request-Response) 模型 。开发者构建一条完整的、自包含的查询语句,将其发送给数据库服务器。服务器解析、优化并执行该查询,然后返回一个静态的、二维的表格作为最终结果 。这个结果一旦生成,就不会再改变,除非用户发起一条新的查询。整个过程是离散的、一次性的。
相比之下,DAX 运行在一个动态交互 (Dynamic Interaction) 的环境中 。开发者定义的是一个“度量值 (Measure)”,它本质上是一个可重用的计算逻辑模板。这个度量值本身并不产生结果,直到它被放置在报告的某个视觉对象中 。当用户与报告交互时——例如,点击切片器、在图表中进行交叉筛选或下钻——同一个度量值会被实时地、反复地在不同的评估上下文中重新计算,动态地展示出相应的结果 。DAX 的计算是持续的、与用户交互紧密耦合的,是构建一个“活”的分析体验的核心。
3.2 集合思维 vs. 上下文思维
SQL 的核心是集合思维 (Set-Based Thinking)。开发者通过 FROM 和 JOIN 子句明确定义一个初始的数据集合,然后通过 WHERE 子句对这个集合进行筛选,最后通过 GROUP BY 子句将筛选后的集合划分为多个子集进行聚合 。整个逻辑链条是显式的、线性的,开发者完全掌控着数据处理的每一步。
DAX 的核心则是上下文思维 (Context-Based Thinking)。开发者编写的度量值公式,在定义时通常是“上下文无关”的,它并不知道自己最终会在何种筛选条件下被调用 。公式的计算结果完全取决于外部环境(即视觉对象和用户交互)所提供的评估上下文 。开发者的任务,从“定义一个完整的计算过程”转变为“设计一个在任何可能的上下文中都能正确行为的计算逻辑”。为此,他们必须熟练运用 CALCULATE、ALL、KEEPFILTERS 等函数来主动地查询、修改或忽略传入的上下文,以实现复杂的业务需求 。

3.3 显式连接 vs. 隐式关系
在 SQL 中,表与表之间的关系是在查询时通过 JOIN 子句显式建立的。开发者在每一条查询中都必须明确指定要连接的表、连接的列以及连接的类型(INNER, LEFT, RIGHT 等)。这种方式给予了开发者对单次查询数据整合的完全控制权。
在 DAX 中,表与表之间的关系是在数据模型中预先定义好的,通常是基于星型模式的“一对多”关系。在公式计算时,这些关系被隐式地使用 。当一个公式需要跨表取值时,开发者不会写 JOIN,而是使用 RELATED 或 RELATEDTABLE 这样的关系函数 。RELATED 函数可以从“多”端(如事实表)沿着关系“走向”到“一”端(如维度表)获取相关的值。引擎会自动根据模型中定义的关系路径来查找数据。这种方式极大地简化了公式的书写,使得业务逻辑的表达更加自然,但也要求开发者对数据模型的结构和关系传播行为有深刻的理解。

3.4 学习曲线的陡坡:SQL 专家的 DAX 陷阱
正是由于上述思维范式的差异,许多经验丰富的 SQL 专家在初学 DAX 时会掉入一些典型的“陷阱”:
- 对表达式进行聚合: SQL 用户习惯于
SUM(单价 * 数量)这样的写法。但在 DAX 中,SUM这样的标准聚合函数只能接受单列引用。正确的做法是使用迭代函数,如SUMX('订单表', [单价] * [数量]),它会创建行上下文,逐行计算表达式,然后将结果聚合 39。 - 度量值返回表: SQL 查询可以返回多行多列的结果集。但 DAX 的度量值必须返回一个单一的标量值。试图让度量值返回一个表(例如,
VALUES('产品'[颜色]))会导致错误。如果需要呈现列表,必须使用CONCATENATEX等函数将表中的多行结果聚合成一个文本字符串 39。 - 在源端预聚合数据: SQL 专家的本能是利用 SQL 的强大能力,在数据加载之前就进行分组和聚合 (
GROUP BY),以减小数据量。然而,这对于 Power BI 来说是一个典型的反模式。这样做会破坏数据的粒度,使得 DAX 无法进行灵活的、动态的分析。最佳实践是使用 SQL 将数据清洗和塑造成一个干净、明细的星型模式,然后将最细粒度的数据加载到 Power BI 模型中,把聚合计算的任务完全交给 DAX 度量值 28。 - 滥用计算列: 为了模拟 SQL 中逐行计算的逻辑,初学者往往会创建大量的计算列。虽然计算列有其用途,但它们是在数据刷新时计算并固化在模型中的,会消耗内存和增加刷新时间。绝大多数的业务计算都应该通过动态的度量值来实现,这样既节省资源,又能响应用户的实时交互 41。
最终,成熟的数据解决方案并非“SQL 与 DAX”的对决,而是“SQL 而后 DAX”的协作。最佳实践是将两者结合,各司其职:利用 SQL 和数据库引擎的强大能力完成上游的数据准备、清洗和转换工作,构建一个结构优良的星型模式;然后,利用 DAX 和 VertiPaq 引擎的内存计算和上下文感知能力,在这个模型之上构建灵活、动态、高性能的分析应用 41。强行让一种语言去承担另一种语言更擅长的工作,只会导致效率低下和架构混乱 44。
| 方面 | SQL (数据库范式) | DAX (分析范式) |
| 核心哲学 | 声明式,面向集合,关注数据存储的完整性和一致性。 | 函数式,面向上下文,关注业务逻辑的动态和交互式计算。 |
| 主要操作单元 | 静态的、完整的查询语句 (SELECT, INSERT, UPDATE)。 | 动态的、可重用的计算公式(度量值、计算列)。 |
| 数据结构 | 规范化的关系模型(如 3NF),旨在消除数据冗余。 | 反规范化的维度模型(星型模式),旨在优化分析查询。 |
| 关系处理 | 在查询时通过 JOIN 子句显式定义和激活。 | 在模型中预先定义,通过关系函数(如 RELATED)隐式使用。 |
| 计算模型 | 请求-响应模型:发送一个查询,接收一个静态的结果集。 | 交互式模型:公式在不同的用户交互上下文中被动态地重新计算。 |
| 典型用例 | OLTP 系统的数据管理、ETL 过程中的数据转换和塑造。 | Power BI、SSAS Tabular 中的商业智能分析、KPI 计算和动态报表。 |
| SQL 概念 | DAX 等效/方法 | 关键思维转变 |
SELECT... WHERE... | CALCULATE(<表达式>, <筛选条件>) | 从静态筛选一个集合,转变为动态修改已存在的筛选上下文。 |
GROUP BY | 视觉对象的行列布局(隐式);SUMMARIZE, GROUPBY 函数(显式)。 | 从对静态集合进行分区,转变为由外部环境(视觉对象)决定分组上下文。 |
JOIN | 模型中的关系 + RELATED(), RELATEDTABLE() | 从在查询时临时连接,转变为利用预定义的、持久的关系路径。 |
SUM(col1 * col2) | SUMX(<table>, [col1] * [col2]) | 从对列的直接操作,转变为创建行上下文并逐行迭代计算。 |
| 子查询 / CTE | 变量 (VAR);表函数作为 CALCULATE 或迭代器的参数。 | 从构建中间结果集,转变为在单个公式内通过变量或嵌套表函数来组织复杂逻辑。 |
窗口函数 (RANK, ROW_NUMBER) | RANKX(<table>, <表达式>) | 迭代器 RANKX 同样需要理解行上下文和筛选上下文的交互。 |
第四部分:两种语言,两个世界
通过对《The Definitive Guide to DAX》和《DAX 别裁新解》的深入剖析,本报告系统地阐明了“SQL 向左,DAX 向右”所代表的深刻分野。结论是明确的:SQL 与 DAX 之争,并非孰优孰劣,而是“使命”与“场景”的根本不同。它们是为不同分析世界设计的语言,并各自催生了独特的思维模式。
- SQL,作为数据世界的通用语和基石,其力量在于其广度、严谨性和对数据结构的底层控制能力。它服务于数据的构建、管理和精确提取,是数据架构师手中塑造数据世界的刻刀。其思维模式是结构化的、确定的,旨在从一个庞大而有序的系统中,获取一个静态但可靠的真理。
- DAX,作为现代商业智能的引擎,其力量在于其深度、灵活性和对业务逻辑的动态封装能力。它服务于数据的探索、交互和洞察发现,是分析工程师和业务分析师手中探索商业价值的罗盘。其思维模式是上下文驱动的、动态的,旨在构建一个能够响应无穷变化的业务场景、并从中即时生成意义的分析模型。

对于希望跨越这一分野的数据专业人士而言,两部著作提供了互补的路径:
- 《The Definitive Guide to DAX》 是不可或缺的、详尽的 DAX 世界地图。它教授这片新大陆独特的地理风貌和物理法则,要求学习者沉浸其中,以内生的方式思考。对于决心成为 DAX 专家的从业者来说,这是一条必经之路。
- 《DAX 别裁新解》 则是一本充满洞见的旅行指南。它帮助来自 SQL 世界的“游客”,通过与他们熟悉的语言和概念进行对比,更快地理解当地的“风土人情”和思维习惯。对于寻求快速建立概念框架、理解 DA-X-在分析生态中定位的学习者,它提供了一条宝贵的捷径。
最终,“向左”还是“向右”的选择,取决于分析任务的终点:是需要交付一份静态、权威的报告,还是构建一个动态、交互的分析模型。精通两种范式,并能在两者之间自如切换,将是未来顶尖数据专业人士的核心竞争力。
结论:融合与未来 —— 范式边界的模糊化
尽管 SQL 和 DAX 分别代表了数据库和分析两大范式的典型思想,但现代数据平台的演进趋势,正是在模糊这两者之间的严格界限。未来的数据架构不再是孤立的系统,而是趋向于融合与协同,吸纳双方的优势,以应对日益复杂和实时的数据分析需求。
这一融合趋势在现代分布式查询引擎中表现得尤为明显,其中 Apache Spark SQL 和 Presto (现为 Trino) 是杰出的代表。
Apache Spark SQL 的出现,旨在将传统关系型数据库的处理能力与 Spark 强大的分布式、内存计算框架相结合 。它引入了 DataFrame 和 Dataset 的概念,这是一种分布式的数据集合,但在逻辑上等同于关系数据库中的表,可以使用列名进行操作 。开发者可以通过标准的 SQL 查询或功能强大的 DataFrame API 对存储在 HDFS、Hive、各类数据库甚至流数据源中的海量数据进行高性能的交互式查询 。其核心优化器 Catalyst 能够理解查询的逻辑结构,并生成高效的物理执行计划 。Spark SQL 的成功表明,SQL 这一声明式的、被广泛接受的查询接口,完全可以作为前端,驾驭一个为大规模分析而设计的、基于内存的分布式计算后端。
Presto/Trino 则将这一理念推向了极致。它被设计为一个纯粹的分布式 SQL 查询引擎,其核心特点是计算与存储分离 。Presto 本身不存储任何数据,而是通过其可插拔的连接器 (Connector) 架构,去查询位于任何地方的数据,无论是数据湖(如 HDFS, S3)、数据仓库(如 Hive, Snowflake)、还是传统的 RDBMS(如 MySQL, PostgreSQL),甚至是 NoSQL 数据库(如 Cassandra, MongoDB)。用户只需通过统一的 ANSI SQL 接口,就可以对来自不同系统的多个数据源进行联邦查询 (Federated Query),实现数据的原地分析而无需进行昂贵的数据迁移 。Presto 的架构体现了对 SQL 作为通用分析语言的极致信任,并将其应用于一个高度异构和分布式的现代数据环境中。
这些新兴技术的崛起预示着,数据库范式与分析范式的核心优势正在被有机地结合起来。列式存储、内存计算、大规模并行处理(MPP)这些曾经主要与专用分析系统相关的技术,正在被整合到支持标准 SQL 接口的通用计算框架中。
最终,对于数据专业人士而言,“SQL 向左,DAX 向右”的二元对立正在演变为一个更加广阔和统一的知识谱系。精通 SQL 意味着掌握了数据结构化、ETL 和大规模数据处理的通用语言;而精通 DAX 则意味着掌握了构建深度交互、业务语义丰富的分析模型的艺术。未来的数据专家必须是“双语”甚至“多语”的,他们需要深刻理解何时应运用 SQL 的严谨与规模来奠定坚实的数据基础,又何时应发挥 DAX 的灵活与动态来创造富有洞察力的分析体验。选择不再是向左或向右的单行道,而是在一个连续的光谱上,根据具体业务问题,明智地选择最合适的工具和思维范式,从而构建出真正驱动价值的端到端数据解决方案。
引用
- OLTP vs. OLAP: Differences and Applications – Snowflake, 访问时间为 十月 8, 2025, https://www.snowflake.com/en/fundamentals/olap-vs-oltp-the-differences/
- OLTP vs OLAP: Key Differences, Examples, and Use Cases for Beginners – Estuary, 访问时间为 十月 8, 2025, https://estuary.dev/blog/oltp-vs-olap/
- OLTP vs. OLAP Explained – Aerospike, 访问时间为 十月 8, 2025, https://aerospike.com/blog/oltp-vs-olap/
- OLTP vs OLAP – Difference Between Data Processing Systems – AWS, 访问时间为 十月 8, 2025, https://aws.amazon.com/compare/the-difference-between-olap-and-oltp/
- OLTP vs OLAP – Real performance differences? : r/dataengineering – Reddit, 访问时间为 十月 8, 2025, https://www.reddit.com/r/dataengineering/comments/1ilpzw1/oltp_vs_olap_real_performance_differences/
- Relational model – Wikipedia, 访问时间为 十月 8, 2025, https://en.wikipedia.org/wiki/Relational_model
- 4.3 Declarative Programming – Composing Programs, 访问时间为 十月 8, 2025, https://www.composingprograms.com/pages/43-declarative-programming.html
- IBM System R – Wikipedia, 访问时间为 十月 8, 2025, https://en.wikipedia.org/wiki/IBM_System_R
- Database normalization description – Microsoft 365 Apps, 访问时间为 十月 8, 2025, https://learn.microsoft.com/en-us/troubleshoot/microsoft-365-apps/access/database-normalization-description
- Database Normalization: 1NF, 2NF, 3NF & BCNF Examples – DigitalOcean, 访问时间为 十月 8, 2025, https://www.digitalocean.com/community/tutorials/database-normalization
- A Brief Guide to Database Normalization | by Leah Nguyen – Medium, 访问时间为 十月 8, 2025, https://medium.com/@ndleah/a-brief-guide-to-database-normalization-5ac59f093161
- Database Normalization – Normal Forms 1nf 2nf 3nf Table Examples, 访问时间为 十月 8, 2025, https://www.freecodecamp.org/news/database-normalization-1nf-2nf-3nf-table-examples/
- Declarative Programming: SQL, HTML, CSS, Prolog Guide – DEV Community, 访问时间为 十月 8, 2025, https://dev.to/vaib/declarative-programming-sql-html-css-prolog-guide-nd0
- Is SQL declarative? – Software Engineering Stack Exchange, 访问时间为 十月 8, 2025, https://softwareengineering.stackexchange.com/questions/200319/is-sql-declarative
- Is SQL a declarative language – Medium, 访问时间为 十月 8, 2025, https://medium.com/@Scudata/is-sql-a-declarative-language-3b91902484d6
- SQL Commands | DDL, DQL, DML, DCL and TCL Commands …, 访问时间为 十月 8, 2025, https://www.geeksforgeeks.org/sql/sql-ddl-dql-dml-dcl-tcl-commands/
- SQL Commands: DDL, DML, DCL, TCL, DQL (With Examples) – InterviewBit, 访问时间为 十月 8, 2025, https://www.interviewbit.com/blog/sql-commands/
- How to Use Views and Stored Procedures in MySQL | Vultr Docs, 访问时间为 十月 8, 2025, https://docs.vultr.com/how-to-use-views-and-stored-procedures-in-mysql
- Basics: View vs Stored Procedure vs Function – Medium, 访问时间为 十月 8, 2025, https://medium.com/@mayurkoshti12/basics-view-vs-stored-procedure-vs-function-04708c2f984b
- Power Pivot – Wikipedia, 访问时间为 十月 8, 2025, https://en.wikipedia.org/wiki/Power_Pivot
- MS PowerPivot: MS’s answer to self serviced BI? | element61, 访问时间为 十月 8, 2025, https://www.element61.be/en/resource/microsoft-powerpivot-microsofts-answer-self-serviced-bi
- Data Analysis Expressions – Wikipedia, 访问时间为 十月 8, 2025, https://en.wikipedia.org/wiki/Data_Analysis_Expressions
- Power Pivot – Overview and Learning – Microsoft Support, 访问时间为 十月 8, 2025, https://support.microsoft.com/en-au/office/power-pivot-overview-and-learning-f9001958-7901-4caa-ad80-028a6d2432ed
- Microsoft Power BI – Wikipedia, 访问时间为 十月 8, 2025, https://en.wikipedia.org/wiki/Microsoft_Power_BI
- VertiPaq (xVelocity) – Simon Späti, 访问时间为 十月 8, 2025, https://www.ssp.sh/brain/vertipaq/
- Learn About The Brain & Muscles of PowerBI … – AlphaBOLD, 访问时间为 十月 8, 2025, https://www.alphabold.com/brain-muscles-of-powerbi/
- Things To Know about VertiPaq engine – ALT-Enter LLC, 访问时间为 十月 8, 2025, https://www.altentertraining.com/wp-content/uploads/Vertipaq-storage.pdf
- SQL VS DAX mental Set – Microsoft Fabric Community, 访问时间为 十月 8, 2025, https://community.fabric.microsoft.com/t5/DAX-Commands-and-Tips/SQL-VS-DAX-mental-Set/m-p/1085406
- Demystifying [DAX] Evaluation Context (with Brian Grant) – YouTube, 访问时间为 十月 8, 2025, https://www.youtube.com/watch?v=hs3T2YF0ewg
- Understanding DAX Evaluation Context: A Comprehensive Guide …, 访问时间为 十月 8, 2025, https://www.metisbi.co.uk/blog/understanding-dax-through-the-power-of-evaluation-context
- Stairway to DAX and Power BI – Level 13: Simple Context Manipulation: Introducing the DAX All() Function – SQLServerCentral, 访问时间为 十月 8, 2025, https://www.sqlservercentral.com/steps/stairway-to-dax-and-power-bi-level-13-simple-context-manipulation-introducing-the-dax-all-function
- Row Context and Filter Context in DAX – SQLBI, 访问时间为 十月 8, 2025, https://www.sqlbi.com/articles/row-context-and-filter-context-in-dax/
- Context in DAX Formulas – Microsoft Support, 访问时间为 十月 8, 2025, https://support.microsoft.com/en-au/office/context-in-dax-formulas-2728fae0-8309-45b6-9d32-1d600440a7ad
- DAX – Nested Calculated queries – Stack Overflow, 访问时间为 十月 8, 2025, https://stackoverflow.com/questions/49653486/dax-nested-calculated-queries
- Learning Evaluation Context – Story BI, 访问时间为 十月 8, 2025, https://storybi.com/2024/01/28/power-bi-evaluation-context/
- Microsoft Power BI vs Microsoft SQL – sbPowerDev, 访问时间为 十月 8, 2025, https://www.sbpowerdev.com/microsoft-power-bi-vs-microsoft-sql/
- What to do in SQL vs in Power BI? : r/PowerBI – Reddit, 访问时间为 十月 8, 2025, https://www.reddit.com/r/PowerBI/comments/1ec3uyj/what_to_do_in_sql_vs_in_power_bi/
- DAX in Analysis Services tabular models – Microsoft Learn, 访问时间为 十月 8, 2025, https://learn.microsoft.com/en-us/analysis-services/tabular-models/understanding-dax-in-tabular-models-ssas-tabular?view=sql-analysis-services-2025
- DAX Measures in SQL Capable Hands – Xomnia, 访问时间为 十月 8, 2025, https://xomnia.com/post/dax-measures-in-sql-capable-hands/
- Evaluation Contexts in DAX – Relationships | endjin – Azure Data Analytics Consultancy UK, 访问时间为 十月 8, 2025, https://endjin.com/blog/2022/01/evaluation-contexts-in-dax-relationships
- SQL VS DAX mental Set – Microsoft Fabric Community, 访问时间为 十月 8, 2025, https://community.fabric.microsoft.com/t5/DAX-Commands-and-Tips/SQL-VS-DAX-mental-Set/m-p/1085957
- Streamlining Financial Analysis: DAX vs SQL – Vibe CFO, 访问时间为 十月 8, 2025, https://vibecfo.ai/blog/streamlining-financial-analysis-dax-vs-sql
- Please explain the relationship between SQL, DAX and PBI like I’m 5 : r/PowerBI – Reddit, 访问时间为 十月 8, 2025, https://www.reddit.com/r/PowerBI/comments/x8aabp/please_explain_the_relationship_between_sql_dax/
- Good Practice Question: Using DAX vs Doing Everything in the Database – Stack Overflow, 访问时间为 十月 8, 2025, https://stackoverflow.com/questions/68214090/good-practice-question-using-dax-vs-doing-everything-in-the-database
- Spark SQL: Explained by ThirdEye Data, 访问时间为 十月 8, 2025, https://thirdeyedata.ai/spark-sql/
- Spark SQL, DataFrames and Datasets Guide, 访问时间为 十月 8, 2025, https://spark.apache.org/docs/latest/sql-programming-guide.html
- What is Spark? – Introduction to Apache Spark and Analytics – AWS, 访问时间为 十月 8, 2025, https://aws.amazon.com/what-is/apache-spark/
- PrestoDB, Presto, PrestoSQL: Open source distributed SQL query engine – Starburst, 访问时间为 十月 8, 2025, https://www.starburst.io/learn/presto-sql/
- What Is Presto? | IBM, 访问时间为 十月 8, 2025, https://www.ibm.com/think/topics/presto
An introduction to the PRESTO architecture – Alluxio, 访问时间为 十月 8, 2025, https://www.alluxio.io/learn/presto/architecture
Pingback: 如何选择BI工具:Power BI“向左”,Tableau“向右”
评论已关闭。