从数据到信息
从信息到洞察

理解 SELECTCOLUMNS

SELECTCOLUMNS

SELECTCOLUMNS ( <Table>, <Name>, <Expression>, [<Name>, <Expression>], [ … ] )

SELECTCOLUMNS 从表或返回表的表达式中选择现有的列,并添加新的列,输出的每个列需要提供一个用作列名的字符串和一个标量表达式,SELECTCOLUMNS迭代函数,每个表达式在<Table>的行上下文中求值。

参数 属性 描述
Table 从中选择列的表
Name 可重复 要添加的新列的名称
Expression 可重复 要添加的新列的表达式
SELECTCOLUMNS 不能在早期的 DAX 引擎中使用

SELECTCOLUMNS 与 ADDCOLUMNS

你可以使用以下查询重写 ADDCOLUMNS 一文中的最后一个示例:

EVALUATE
SELECTCOLUMNS (
    Product,
    "ProductKey", Product[ProductKey],
    "Product Name", Product[Product Name],
    "Price", Product[Unit Price]
)
ORDER BY [ProductKey]

结果是相同的,但有一个重要的区别:所有列都来自模型的物理列,对于 Product Name 和 Price 列都是如此,后者对应于 Unit Price,即使你更改了 SELECTCOLUMNS 输出列的名称。

SELECTCOLUMNS 与 ADDCOLUMNS 具有相同的函数签名(存储在编译器内部的名称、参数等信息),并且具有相同的行为,只不过 ADDCOLUMNS 从指定的<table>开始添加列,而 SELECTCOLUMNS 从空表开始在添加列。

关于数据沿袭

SELECTCOLUMNS 默认保留列的沿袭Lineage)。如果执行重命名操作,只要表达式引用的是数据模型的现有列,结果就会使用相同的数据沿袭映射该列,而一旦使用任何表达式,你就失去了沿袭。你将在数据沿袭一文中看到更详细的解释。

关于命名

无论是否具有沿袭,对 SELECTCOLUMNS 定义的列的任何引用都必须使用指定给该列的准确名称。因此,如果定义列使用的是不完全限定名,则后续引用语法必须使用不加表名的列名。例如,以下语法是无效的:

EVALUATE
FILTER (
    SELECTCOLUMNS (
        Product,
        "ProductKey", Product[ProductKey],
        "Product Name", Product[Product Name],
        "Unit Price", Product[Unit Price]
    ),
    Product[Unit Price] > 10
)
ORDER BY [ProductKey]

查询对 Product[Unit Price]的引用无效,因为 SELECTCOLUMNS 在定义此列时使用的名称是 Unit Price。值得注意的是,ORDER BY 子句使用的 ProductKey 没有这个问题,因为它引用的是没有表名的列名。你可以在筛选语句中使用不完全限定名来避免这个问题,如下面的查询所示:

EVALUATE
FILTER (
    SELECTCOLUMNS (
        Product,
        "ProductKey", Product[ProductKey],
        "Product Name", Product[Product Name],
        "Unit Price", Product[Unit Price]
    ),
    [Unit Price] > 10
)
ORDER BY [ProductKey]

你也可以在 SELECTCOLUMNS 中使用完全限定名,以便在后续引用中保持相同的语法,如下一个示例中所示:

EVALUATE
FILTER (
    SELECTCOLUMNS (
        Product,
        "Product[ProductKey]", Product[ProductKey],
        "Product[Product Name]", Product[Product Name],
        "Product[Unit Price]", Product[Unit Price]
    ),
    Product[Unit Price] > 10
)
ORDER BY [ProductKey]

即使为每个列定义了完全限定的名称,仍然可以在引用列时仅使用列名,就像示例中 ORDER BY 引用 ProductKey 列一样。这种语法是有效的,除非在最终结果中有两个列具有相同的列名和不同的表名(在这种情况下,会产生歧义而提示引用错误)。

你还可以使用 SELECTCOLUMNS 添加新列,执行类似 ADDCOLUMNS 函数的操作。区别在于,必须显式引用结果中包含的每一列,而不是直接向当前表添加新列。例如,下面的查询返回每个产品类别的子类别对应的产品数量,只显示类别名称,不显示产品类别表中的其他列:

EVALUATE
SELECTCOLUMNS (
    'Product Category',
    "Category Name", 'Product Category'[Category],
    "Subcategories", CALCULATE ( COUNTROWS ( 'Product Subcategory' ) ),
    "Products", CALCULATE ( COUNTROWS ( Product ) )
)

结果将 Category Name 列映射到模型产品类别表的 Category 列(保持了沿袭),并添加两个以斜体突出显示的计算列,因为它们与物理列没有映射关系。

12
说点什么

1000
 
鼓掌微笑开心憧憬爱你色并不觉得吃瓜doge二哈喵喵思考笑哭捂脸悲伤大哭抓狂汗偷笑打脸捂眼黑线问号晕拜拜闭嘴衰咒骂ok作揖
5 评论数
8 被回复的评论
6 订阅评论的人数
 
查看最近回复
查看最热评论
  订阅本文评论  
最新 最旧 得票最多
提醒
成员
153****1882

不确定之前的提问是不是被隐藏了,再发一下。
高老师,文章最后“你还可以使用 SELECTCOLUMNS 添加新列,执行类似 ADDCOLUMNS 函数的操作。区别在于,必须显式引用结果中包含的每一列,而不是直接向当前表添加新列。”,怎么理解该句中的“必须显式引用结果中包含的每一列,而不是直接向当前表添加新列”?谢谢。

成员
做一名学霸

SELECTCOLUMNS 从表或返回表的表达式中选择现有的列,并添加新的列,输出的每个列需要提供一个用作列名的字符串和一个标量表达式。

老师好~关于这段表述,有些疑问:
1. 从表或返回表的表达式中选择现有的列,并添加新的列——这句话的意思是,第一参数的作用是从选现有的列,用来添加到空表的新建列中吗?
2.从第一参数选择现有的列,包含第一参数扩展表中的列吗?
3.从第一参数选择现有的列后,放在第三参数表达中,然后再给第二参数个列名,就可以通过迭代新建一个列,是这个意思把

成员
fzn002006

作者的翻译,确实读起来比较拗口,无形中增加了不必要的阅读时间成本,建议语法上再优化一下。

成员
lyliuyouyang

你好,我在最近实际使用过程中发现以下问题,我写了table1和table2两种表函数,table1是是先用selectcolumns选出人员考核表中的一些列,然后使用addcolumns添加与这个人员考核创建了关系的其他表里的内容,比如籍贯,民族等,但是在测试种发现table1的related部分报错,说是没有行上下文之类的提示,但是使用table2中的直接进行selectcolumns就可以实现,但是还是使用了related函数。我的疑惑就是selectcolumns如果只是引用原表中的列,没有对列进行计算的话,应该会保持原表中的沿袭才是,但是为什么使用addcolumns添加时失效了呢?麻烦解惑

批注 2020-04-16 093158.jpg
DAX 圣经

导读

初识 DAX

DAX 基础知识

DAX 原理

DAX 高级原理

基础函数类型

迭代函数

CALCULATE 函数

CALCULATE 调节器

基础表函数

条件判断函数

查找匹配函数

时间智能函数

统计类函数

投影函数

分组/连接函数

集合函数

其他函数