DAX 底层计算过程演示——ADDCOLUMNS + 复杂上下文环境

关于 DAX 理论的资料很多,DAX 理论帮助我们理解和预测 DAX 的计算结果,但 DAX 在底层实际是怎么计算的却少有人谈及。本篇以一段在复杂上下文环境中通过 ADDCOLUMNS 进行计算的 DAX 查询代码为观察对象,使用 DAX Stuido 查看查询计划,展示其在存储引擎中执行了哪些数据查询,揭示公式引擎如何组装这些数据最终得出计算结果。

数据环境

数据文件 下载

1、DFact——数据表,由 Date 和 Amount 两列组成

​image​

2、Dates——日期表,由 DAX 代码生成

​image​

3、两张表通过 [Date] 列建立关系,Dates[Date](1) — (*) DFact[Date]

​image​

4、度量值

SumAmount = SUM('DFact'[Amount])
SumxBug = SUMX(VALUES(Dates[Year]),[SumAmount])

DAX 查询代码

EVALUATE
CALCULATETABLE (
    ADDCOLUMNS ( VALUES ( Dates[Year] ), "SumxBug", [SumxBug] ),
    TREATAS (
        { ( 2019, 1 ), ( 2019, 2 ), ( 2020, 11 ), ( 2020, 12 ) },
        'Dates'[Year],
        'Dates'[Month Num]
    )
)

​CALCULATETABLE​ 以 TREATAS​ 作为调节器,为ADDCOLUMNS​ 提供筛选上下文,ADDCOLUMNS​ 在该上下文中扫描 Dates[Year]​并计算度量值[SumxBug]​

运行结果如下:

​image​

DAX 理论

先用 DAX 理论分析一下计算结果。

下面的图中使用红色数字标记了某些列,这是故意的,后面有用处。

1、CALCULATETABLE​ 以 TREATAS​ 作为调节器,为 ADDCOLUMNS​提供外部筛选器。

​image​

2、在外部筛选上下文中计算 ADDCOLUMNS​ 一参 VALUES(Dates[Year])​

​image​

3、ADDCOLUMNS​以 2# 数据集为迭代对象,逐行读取行上下文,在外部筛选上下文和行上下文中计算[SumxBug]​
SumxBug = SUMX(VALUES(Dates[Year]),[SumAmount])

[SumxBug] 将行上下文转换为筛选上下文,并覆盖外部筛选上下文。

​image​

4、计算 SUMX(VALUES(Dates[Year]),[SumAmount])​

迭代 Dates[Year]​ 并计算 [SumAmount]​ ,这里出现第二层行上下文​
在这里插入图片描述

5、合并成最终的结果

完整的分析流程如下
在这里插入图片描述
注意在这个过程中存在多层行上下文的事实。

DAX 底层计算过程

以下内容将涉及 DAX 引擎和查询计划,相关资料可查看《权威指南》第二版第17、19章。

存储引擎部分

在 DAX Studio 中通过 Server Timings 窗口,了解到存储引一共执行了 3个 xmSQL 查询。

​image​

注意 xmSQL 与标准 SQL 不同,xmSQL 语句中的 SELECT 子句中出现的列会自动进行分组,举个例子,有 xmSQL 代码

// xmSQL
SELECT customer[country], customer[state], SUM ( customer[amount] )
FROM customer

与下面的标准 SQL 代码的作用是一样的

// 标准 SQL
SELECT customer.country, customer.state, SUM ( customer.amount )
FROM customer
GROUP BY customer.country, customer.state

为了方便后文指代,这里将这 Server Timings 窗口中的 3 次查询从上往下分别命名为 VQ1、VQ2、VQ3,每个查询的代码、作用和数据如下。

1、VQ1

以 ( 'Dates'[Year], 'Dates'[Month Num] ) IN { ( 2020, 12 ) , ( 2019, 2 ) , ( 2020, 11 ) , ( 2019, 1 ) }​为条件,从 Dates 表中分组获取 Year 列上的值

// xmSQL VQ1
SELECT
    'Dates'[Year]
FROM 'Dates'
WHERE
     ( 'Dates'[Year], 'Dates'[Month Num] ) IN { ( 2020, 12 ) , ( 2019, 2 ) , ( 2020, 11 ) , ( 2019, 1 ) };

查询结果包含1个字段列

​image​

2、VQ2

以'Dates'[Year] IN ( 2019, 2020 ) VAND 'Dates'[Month Num] IN ( 12, 1, 2, 11 ) ​为条件,从 DFact 的扩展表中按 Dates[Year] 分组汇总 SUM(DFact[Amount])​

// xmSQL VQ2
SELECT
    'Dates'[Year],
    SUM ( 'DFact'[Amount] )
FROM 'DFact'
    LEFT OUTER JOIN 'Dates'
        ON 'DFact'[Date]='Dates'[Date]
WHERE
    'Dates'[Year] IN ( 2019, 2020 ) VAND
    'Dates'[Month Num] IN ( 12, 1, 2, 11 ) ;

查询结果包含1个字段列,1个值列,这里用 Row1 命名该值列

​image​

3、VQ3,F1V0

以'Dates'[Year] IN ( 2019, 2020 ) VAND 'Dates'[Month Num] IN ( 12, 1, 2, 11 ) ​为条件,从 Dates 表中分组获取 Year 列上的值

// xmSQL VQ3
SELECT
    'Dates'[Year]
FROM 'Dates'
WHERE
    'Dates'[Year] IN ( 2019, 2020 ) VAND
    'Dates'[Month Num] IN ( 12, 1, 2, 11 ) ;

查询结果包含1个字段列
​image‍

注意在 3 次查询中, VQ1 与 VQ3 的查询结果完全相同,但 WHERE 子句内容不同。

公式引擎部分

在 DAX Studio 中通过 Query Plan 窗口可以查看逻辑查询计划和物理查询计划
​image​

逻辑查询计划略过,物理查询计划完整截图如下:

在这里插入图片描述
​
按照缩进关系画出树状线,方便了解结构层次。

AddColumns: IterPhyOp LogOp=AddColumns IterCols(3, 4)('Dates'[Year], ''[Total])
├── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=Scan_Vertipaq IterCols(3)('Dates'[Year]) #Records=2 #KeyCols=10 #ValueCols=0
│   └── ProjectionSpool<ProjectFusion<>>: SpoolPhyOp #Records=2
│       └── Cache: IterPhyOp #FieldCols=1 #ValueCols=0
│           └── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num]) #Records=4 #KeyCols=2 #ValueCols=0
│               └── AggregationSpool<GroupBy>: SpoolPhyOp #Records=4
│                   └── TreatAs: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num])
│                       └── TableCtor: IterPhyOp LogOp=TableCtor IterCols(0, 1, 2)(''[Value1], ''[Value2], ''[])
└── SpoolLookup: LookupPhyOp LogOp=SumX LookupCols(3)('Dates'[Year]) Integer #Records=2 #KeyCols=1 #ValueCols=1 DominantValue=BLANK
    └── AggregationSpool<Sum>: SpoolPhyOp #Records=2
        └── CrossApply: IterPhyOp LogOp=Sum_Vertipaq IterCols(4)('Dates'[Year])
            ├── Spool_MultiValuedHashLookup: IterPhyOp LogOp=Scan_Vertipaq LookupCols(4)('Dates'[Year]) IterCols(3)('Dates'[Year]) #Records=2 #KeyCols=10 #ValueCols=0
            │   └── ProjectionSpool<ProjectFusion<>>: SpoolPhyOp #Records=2
            │       └── Cache: IterPhyOp #FieldCols=1 #ValueCols=0
            │           ├── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num]) #Records=4 #KeyCols=2 #ValueCols=0
            │           │   └── AggregationSpool<GroupBy>: SpoolPhyOp #Records=4
            │           │       └── TreatAs: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num])
            │           │           └── TableCtor: IterPhyOp LogOp=TableCtor IterCols(0, 1, 2)(''[Value1], ''[Value2], ''[])
            │           └── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=Scan_Vertipaq IterCols(3)('Dates'[Year]) #Records=2 #KeyCols=10 #ValueCols=0
            │               └── ProjectionSpool<ProjectFusion<>>: SpoolPhyOp #Records=2
            │                   └── Cache: IterPhyOp #FieldCols=1 #ValueCols=0
            │                       └── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num]) #Records=4 #KeyCols=2 #ValueCols=0
            │                           └── AggregationSpool<GroupBy>: SpoolPhyOp #Records=4
            │                               └── TreatAs: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num])
            │                                   └── TableCtor: IterPhyOp LogOp=TableCtor IterCols(0, 1, 2)(''[Value1], ''[Value2], ''[])
            └── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=Sum_Vertipaq IterCols(4)('Dates'[Year]) #Records=2 #KeyCols=10 #ValueCols=1
                └── ProjectionSpool<ProjectFusion<Copy>>: SpoolPhyOp #Records=2
                    └── Cache: IterPhyOp #FieldCols=1 #ValueCols=1
                        └── Spool_Iterator<SpoolIterator>: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num]) #Records=4 #KeyCols=2 #ValueCols=0
                            └── AggregationSpool<GroupBy>: SpoolPhyOp #Records=4
                                └── TreatAs: IterPhyOp LogOp=TreatAs IterCols(0, 1)('Dates'[Year], 'Dates'[Month Num])
                                    └── TableCtor: IterPhyOp LogOp=TableCtor IterCols(0, 1, 2)(''[Value1], ''[Value2], ''[])

为了更好地了解物理查询计划的结构,按照层次关系绘制流程结构图。
在这里插入图片描述

图中每个方块各代表一行代码,对应关系如下图所示。

​image​

绿色方块代表数据操作,棕色方块代表 xmSQL 查询的数据缓存,蓝色方块代表其他

底层计算过程

在物理查询的流程结构图上标出各部分生成和组装的数据,从下往上看。

建议右键点击图片,选择【在新标签页中打开图像】以查看大图,详细了解各个部分的说明。

​image​

几个说明

1、VQ2 的 WHERE 子句

回顾一下存储引擎执行的 xmSQL VQ2 的内容,WHERE 子句以 Dates[Year] IN ( 2019, 2020 )​ 和 Dates[Month Num] IN ( 12, 1, 2, 11 )​做条件

SELECT
    'Dates'[Year],
    SUM ( 'DFact'[Amount] )
FROM 'DFact'
    LEFT OUTER JOIN 'Dates'
        ON 'DFact'[Date]='Dates'[Date]
WHERE
    'Dates'[Year] IN ( 2019, 2020 ) VAND
    'Dates'[Month Num] IN ( 12, 1, 2, 11 ) ;

DAX 查询代码中,CALCULATETABLE​ 使用 TREATAS​ 构建的固化筛选器作为 ADDCOLUMNS​ 的筛选上下文,为什么这里的 xmSQL 没有使用固化筛选器,而是将 Year 和 Month Num 拆开了?

如果以固化筛选器为条件,这里的 WHERE 子句应该是这样:

WHERE ( 'Dates'[Year], 'Dates'[Month Num] ) IN { ( 2020, 12 ) , ( 2019, 2 ) , ( 2020, 11 ) , ( 2019, 1 ) }

对照上一节的 DAX 理论分析,真正需要的计算发生在 [SumAmount] = SUM(DFact[Amount])​ 这部分,这一部分的计算上下文是什么?

是下图中红框标记出来的这部分,包括 Year = {2019,2020} 和 Month Num = {1, 2, 11, 12},DAX 底层根据对代码的理解,对存储引擎申请的数据查询直接使用了该条件作为 WHERE 子句。
在这里插入图片描述

2、为什么 VQ1 和 VQ3 重复查询 Dates[Year]

理论分析部分出现过两个迭代器,均以 Dates[Year] 为迭代对象,形成两套行上下文。

回顾下这两个迭代器的计算上下文:

1)第一个迭代器 ​ADDCOLUMNS​​ 计算一参时

​image​

以 TREATAS 构建的固化筛选器为条件,这对应了 VQ1 的 WHERE 子句

// xmSQL VQ1
SELECT
    'Dates'[Year]
FROM 'Dates'
WHERE
     ( 'Dates'[Year], 'Dates'[Month Num] ) IN { ( 2020, 12 ) , ( 2019, 2 ) , ( 2020, 11 ) , ( 2019, 1 ) };

2)第二个迭代器 ​SUMX​​ 计算一参时

​image​

以 [Year] = {2019,2020} AND [Month Num] = {1, 2, 11, 12} 为条件,对应了 VQ3 的 WHERE 子句

// xmSQL VQ3
SELECT
    'Dates'[Year]
FROM 'Dates'
WHERE
    'Dates'[Year] IN ( 2019, 2020 ) VAND
    'Dates'[Month Num] IN ( 12, 1, 2, 11 ) ;

由此可知:

  • VQ1 对应了 ADDCOLUMNS(VALUES(Dates[Year]),...)​中的 VALUES(Dates[Year])​,对应第一层行上下文

  • VQ3 对应了 SUMX(VALUES(Dates[Year]),...)​ 中的 VALUES(Dates[Year])​,对应第二层行上下文

存储引擎需要执行两个 xmSQL 查询,重复获取 Dates[Year] 的值,正是基于有两个迭代器需要在不同的上下文中扫描Dates[Year]。

3、物理查询计划流程结构图中 3# 号框在做什么?

​image​

从数据表来看,这一步的作用是将 VQ2 与 VQ3 通过 [Year] 的 hash 值进行匹配合并,在本案例中,VQ2 和 VQ3 是一对一的关系( VQ2(1)—(1)VQ3),合并后的结果有2行。

4、为什么要将 Year(4) 和 Year(3) 合并到一张表里?

因为再往上,ADDCOLUMNS​ 操作符需要使用 Year(3) 查找对应值,而 VQ2 数据缓存中保存的是 Year(4),不是 Year(3),无法直接进行查找。虽然是同一列,但 DAX 底层会区分来自不同来源的同一列,Year(4) 来自 VQ2,Year(3) 来自 VQ1。

3#号框将 Year(4) 和 Year(3) 匹配合并到一张表中,使得 ADDCOLUMNS​ 可以从其中通过 Year(3) 找到对应的 Row1 值,形成最终的结果表。

​image​

DAX 理论与实际计算过程的关系

有了以上分析后,现在可以将 DAX 理论、存储引擎、公式引擎3者的关系,标记在同一张图上。
(使用鼠标右键点击该图片,选择 “在新标签页中打开图像” 以查看大图)
在这里插入图片描述
​‍
以上便是关于这段 DAX 查询代码,CALCULATETABLE​ 以 TREATAS​ 作为调节器,为ADDCOLUMNS​ 提供筛选上下文,ADDCOLUMNS​ 在该上下文中扫描 Dates[Year]​并计算度量值[SumxBug]​ 的过程。

其他

这里我给度量值取的名称叫 SumxBug,是因为如果在 PowerBI 搭建报表完成完全相同的计算时会出现 bug,得到不一样的结果,如下图所示

​image​

在计算 2019 年的 [SumxBug] 时,实际是将 2019 年 1、2 月和 2020 年 1、2 月的 Amount 累加了起来,1+2+13+14 = 30

在计算 2020 年的 [SumxBug] 时,实际是以 2019 年 11、12 月和 2020 年 11 月、12 月的 Amount 来算的,11+12+23+24 = 70

PowerBI 计算出的结果与 DAX 理论预测的结果不符,与 CALCULATETABLE​ + ADDCOLUMNS​ 计算得到的结果不一致,这是由于 PowerBI 中计算报表时使用了 SUMMARIZECOLUMNS​,关于 SUMMARIZECOLUMNS​ 的 bug,可以跳转到下面这篇文章进行了解。

《SUMMARIZECOLUMNS 的疑似 bug(1)引言》

DAX Studio学习笔记_1 学习地址:PowerBI.Tips - Tutorial - Introduction to DAX Studio - By Darren Gosbell - YouTube 系列文章 目录 系列文章 一、DAX Studio是什么? 二、使用 1、连接数据时出现很多时间维度表 2、属性显示 3、多个连接 4、使用EVALUATE, DEFINE, MEASURE 5、DAX Format 6、查找/替换关键词 7、使用report a bug功能 8、Metadata,Fu... 阅读详情

相关推荐

浅谈DAX中的上下文概念

介绍DAX中的行上下文和筛选上下文的基本概念。

Fluffy的百宝箱 6757

DAX :表值函数 ADDCOLUMNS 和 SELECTCOLUMNS

函数ADDCOLUMNS和SELECTCOLUMNS的功能相似,都是迭代函数,在行下文中计算表达式,并返回一个表,但是从数据沿袭的角度来看: 在ADDCOLUMNS函数中,添加的列不具有数据沿袭的能力。 在SELECTCOLUMNS函数中,SELECTCOLUMNS 保留简单列引用的数据沿袭,对列执行的任何表达式都会破坏数据沿袭。 一,ADDCOLUMNS函数 ADDCOLUMNS是一个迭代...

悦光阴的博客 3284

DAX-期末余额计算

期末余额计算比较常见,比如,存货。DAX功能十分强大,丝毫不逊色MDX。 下面以一个实例说明,分别计算四种情况期末余额: 基本情况,地区表,商店表,数量表,日期表。   第一种情况, 2012 东城:5+3=8 (3/25/2012) 北城:0 南城:0 西城:8 (2/25/2012) 合计:5+3=8 (3/25/2012) 这种计算比较简单, CALCULATE(

MICRO BI 3892

PowerBI之DAX函数精讲和实战【2021版】

目前国内最全DAX函数讲解视频课程,理论结合实战,总共69课时,每个课时目前都是单一且易识别的知识点,方便随时学习和复习自己关心的知识点,主要包含PowerBI建模的知识、DAX函数基础知识、DAX函数原理、DAX函数系统讲解、重点DAX函数详解、DAX函数在PowerBI报表开发和数据分析中的应用 

DAX高手进阶:用VAR变量和表函数写出清晰、高效的复杂公式(告别EARLIER)

本文深入探讨了DAX公式的高级应用,重点介绍如何使用VAR变量和表函数替代传统的EARLIER函数,以编写更清晰、高效的复杂公式。通过实际案例展示了VAR变量在捕获计算上下文、优化性能方面的优势,以及表函数在简化逻辑、提升可读性方面的作用,帮助数据分析师从基础DAX使用进阶到专业水平。

weixin_33686714的博客 394

Power BI中RELATED函数原理与实战:DAX行上下文与星型模型缝合

RELATED是Power BI DAX中实现维度属性注入的核心函数,本质是在行上下文(Row Context)中沿活动关系单向映射关联表字段,而非传统VLOOKUP式查找。其设计严格区分行上下文与筛选上下文,确保语义精准传导,避免动态计算失真。技术价值在于以低开销方式将维度属性‘物理化’注入事实表,支撑灵活分组、钻取分析与上下文感知度量。典型应用场景包括销售明细表注入品类/品牌属性、客户表中计算首次购买天数、雪花模型多级维度穿透,以及与CALCULATE协同构建动态度量。掌握RELATED,即掌握星型模型

weixin_30394981的博客 468

DAX调试进阶:利用DaxStudio精准模拟复杂上下文场景

本文深入探讨了如何利用DaxStudio进行DAX调试,精准模拟复杂上下文场景。通过拆解公式、模拟行上下文和筛选上下文等高级技术,帮助开发者解决DAX计算中的常见问题,提升Power BI开发效率。文章还分享了实战案例和性能优化技巧,是DAX调试的进阶指南。

a3b4c5的博客 856

【脑电信号处理与特征提取】P2-夏晓磊:脑电的神经起源与测量

ElectroEncephaloGraphyTherefore, EEG produces a graphed representation of the electrical activity occurring in a person’s brain.(把一个人的大脑中的电活动画出来)脑电头皮表面记录到的大脑活动产生的电信号(微伏)。(记录位置:硬脑膜/大脑皮层表面- ECoG,神经元群- LFP与MUR/MUA:活动位置:心电、眼电、肌电等)脑电图电压随时间变化的波形图。

m0_51474171的博客 1894

DAX:翻译《使用SUMMARIZE和ADDCOLUMNS添加扩展列》

原文:Best practices using SUMMARIZE and ADDCOLUMNS 在实践中,可以用SUMMARIZE添加分组列,而用ADDCOLUMNS添加计算列。 ADDCOLUMNS( SUMMARIZE( <table>, <group by column>,... ), <column_name>, CALCULATE...

悦光阴的博客 454

Playwright Java环境配置避坑指南:浏览器路径、类加载与离线部署

Playwright作为现代端到端测试框架,其Java SDK突破了传统Selenium的Driver管理模式,将Chromium/Firefox/WebKit内核视为可编程运行时资源。其核心原理在于SDK与浏览器二进制分离——Maven仅管理Java字节码,而浏览器需独立下载、校验与沙箱加载。这一设计带来显著技术价值:跨平台一致性、进程隔离安全性及多浏览器并行能力;典型应用场景涵盖Spring Boot集成测试、金融级离线CI/CD、Kubernetes容器化部署及Air-Gapped封闭环境。然而,因J

weixin_32956805的博客 678

Ubuntu20.04系统Cuckoo sandbox所需环境搭建及安装(超详细图文)

请勿叫我大神,我只是互联网的搬运工~ 前言 本教程以Ubuntu20桌面版作为示范,服务器版同样适用,但可能稍微麻烦一点,服务器版本的话安装Xmanage套装使用可能会相对轻松一些,由于后面会使用到vbox的使用,对vbox命令行操作不熟悉的小伙伴用xmanage可能会相对轻松一点。 提示:以下是本篇文章正文内容,下面案例可供参考 安装ubuntu20桌面版 步骤1:转到https://ubuntu.com/download/desktop下载下载.iso。 步骤2:使用您选择的虚拟机监控程序(VMWa

ElsonHY的博客 1万+

DAX调试实战:利用DaxStudio精准模拟上下文环境验证度量值

本文详细介绍了如何利用DaxStudio工具精准模拟上下文环境来调试和验证DAX度量值。通过实战案例,阐述了使用EVALUATE、ADDCOLUMNS等核心函数构建可控测试环境的方法,帮助开发者高效定位逻辑错误、验证公式准确性,并提升DAX代码的健壮性与性能。

weixin_29232507的博客 579

EEG | CHB-MIT癫痫数据集CNN分类实战(一)

CHB-MIT癫痫数据集CNN分类实战

Always learn from the best. 1万+

DAX权威指南3:变量、迭代函数与计算组

变量可以被定义为一个表达式,该表达式中可以进一步定义其他变量。例如,以下代码中,在外层定义了变量CurrentPrice,但具体的计算逻辑是在内层SUMX中完成的。SUMX ('Product',SUMX (RETURN在处理时间相关的数据时,我们常常需要进行各种时间智能计算,例如年迄今(YTD)、季度迄今(QTD)、去年同期(PY)等。除此之外,还需要考虑各种指标,例如在一个销售数据模型中,我们可能需要计算销售额、总成本、利润率和总销量等。这些度量值为业务提供了不同的见解,都是有用的。

qq_56591814的博客 1394

Spring AI从入门到精通:构建智能Spring应用的全面指南

随着人工智能技术的快速发展,将大语言模型(LLM)与企业应用集成已成为趋势。Spring AI作为Spring官方推出的AI集成框架,为开发者提供了便捷、标准化的方式来构建智能应用。本文将从基础概念到高级应用,全面介绍Spring AI的核心功能与实践技巧。Spring AI 是 VMware 于 2023 年推出的开源框架,旨在简化大语言模型(LLM)与 Spring 应用的集成。它提供了统一的 API 抽象,支持多种 LLM 供应商,包括 OpenAI、Azure OpenAI、Hugging Face

qq_36929638的博客 1069

低轨通信 | 手机直连低轨卫星通信:架构、关键技术与未来展望

手机直连低轨卫星通信正推动人类进入"全域连接"时代。当中国星网GW星座与千帆星座的万颗卫星点亮夜空,当普通智能手机在珠峰之巅仍能流畅视频通话,当远洋渔船通过卫星物联网实现精准捕捞——这些场景不仅重构通信产业格局,更将深刻改变人类生产生活方式。正如工信部《指导意见》所规划,到2030年我国将发展超千万卫星通信用户,催生万亿级新市场[1][5]。在这场太空基建竞赛中,技术创新与标准制定的双重突破,将决定未来数字文明的星空版图。

尘世冰封的专栏 939

PowerBI之DAX 2:聚合、统计、关系、表操作函数

SUM是DAX中最常用的聚合函数,它只有一个参数:<column>销售总额 = SUM( '订单表'[销售额] )<table>:将要进行计算的表,可以是FILTER表表达式计算得到的筛选表:对表中每一行进行计算的表达式所以SUMX返回的就是:对表的每一行按表达式进行计算,再进行求和。销售总额 =SUMX( '订单表','订单表'[销售额] )由于SUM函数只有一个参数,决定了它只能处理一个表的一列的求和,而涉及到多列/多表的计算,或者对特定表达式的求和,它就不适用了。

qq_56591814的博客 4336

piamon实战-- 如何使用 Paimon 的 Java API 实现数据的点查

点查(Point Lookup)是指通过 ​​唯一键(Primary Key)​​ 快速定位并返回单条或少量数据的查询模式。例如:根据用户 ID 查询用户信息、根据订单号查询订单详情等。点查的核心诉求是 ​​低延迟​​ 和 ​​高吞吐​​,适用于实时风控、在线分析等场景。​​定义主键表结构​​,优化数据分布。​​构建过滤条件​​,使用指定查询键。​​执行查询并处理结果​​,结合流式更新实现实时查询。

阿华田的博客 532

列运算_DAX表操作基础第二招:增加列

新建列在现有表格基础上添加一列,最基本的做法,是使用列工具中的新建列:简单实用,就是我们常说的计算列,计算列在模型设计时的作用也很重要,有些逐行生成的值需要固定下来,不再变化的我们就可以使用计算列。ADDCOLUMNS函数最初接触这个函数,大多是学习DAX查询的时候,我们要在Excel中做一个链回表,应该算一个实体表吧,经常看到这样的写法:我们把这句放到Excel表中的DAX查询:就会生成一个这样...

weixin_28295799的博客 2015

电容放电测试解析

电子设备断电后滤波电容残留电荷存在触电风险,需符合IEC等安全标准对放电时间的要求。放电测试需测量电容电压下降至安全值的时间,设计可采用主动放电电路或被动放电电阻。常见问题包括电阻选择不当或电路设计缺陷,建议预留放电时间裕度并采用组合放电方案。合规的放电设计是确保产品安全性和可靠性的关键环节。

硬核科技 802

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

DAX:SUMMARIZE的秘密

作为一个查询函数,SUMMARIZE 执行三个操作: 它可以按表本身或相关表的任何列对表进行分组; 它可以创建新列,在行上下文和过滤上下文中计算表达式; 它可以产生不同级别的小计(subtotal)。 在 SUMMARIZE 的三个主要操作中,只有第一个是安全的。 另外两个操作——创建新列和计算小计——应该避免。 并不是说这些功能不起作用。 问题是 SUMMARIZE 的语义非常复杂,以至于...

悦光阴的博客 2050

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深入理解 Power BI DAX 中 ALLSELECTED 的影子筛选器

深入理解 Power BI DAX 中 ALLSELECTED 的影子筛选器

qingmeizhujiu8的博客 3685

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Dax函数总结

行上下文,可以理解为原始数据中,一行接着一行的排序,这个就叫行上下文,也就是藏在内部的筛选关系,这里称之为隐性筛选。切片器这种,摆在外面的控制器,来影响计算结果,筛选的条件,成为显性筛选。

早八人的上课笔记收录哈哈哈 5873

DAX Studio高级查询分析:如何诊断和优化复杂DAX公式

DAX Studio是Power BI生态系统中不可或缺的终极工具,专为编写、执行和分析DAX查询而设计。无论您是Power BI Desktop用户、Excel Power Pivot开发者还是Analysis Services Tabular分析师,这款免费工具都能帮助您快速诊断和优化复杂DAX公式,显著提升数据分析性能。 ## 🔍 为什么需要DAX公式诊断工具? 在Power BI和E

gitblog_00720的博客 931

union all 数据条数变少_做DAX时间智能函数的朋友(2)UNION( ADDCOLUMNS(SUMMARIZE(CALCULATETABLE就够了!...

一个组合搞定所有时间智能函数应用?UNION(ADDCOLUMNS( SUMMARIZE(CALCULATETABLE('日期表',.....万能组合函数就够了!UNION(ADDCOLUMNS( SUMMARIZE( CALCULATETABLE('日期表'组合,堪称DAX函数中的 SMARTKAYVAR变量+UNION(ADDCOLUMNS( SUMMARIZE( CALCULAT...

weixin_39689297的博客 730

dax powerbi 生成表函数_PowerBI应用技巧:DAX生成的表如何添加索引?

原标题:PowerBI应用技巧:DAX生成的表如何添加索引? 来源于知识星球中一个星友的问题,使用DAX在PowerBI中新建了一个表,如何为这个表添加索引列呢?假如数据模型中只有一张订单表,需要从订单表中提取客户表,可以直接使用VALUES函数提取一个不重复客户表, 如何为这个表添加索引列?因为DAX生成的表无法在PowerQuery中编辑,也就无法使用PQ的添加索引列的功能了,这里提供两个变通...

weixin_31767787的博客 1101
上一篇: SUMMARIZECOLUMNS 的疑似 bug(4)验证触发条件
下一篇: SUMMARIZECOLUMNS 的疑似 bug(5)最终结论
apinerand
博客等级 码龄9年 201粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值