[知识体系] 理解 GENERATE 和 GENERATEALL

  [复制链接]
查看126545 | 回复128 | 2021-2-21 18:50:03 | 显示全部楼层 |阅读模式
GENERATE 函数对 Table1 的每一行计算 Table2,返回 Table1 中每一行与 Table2 的相应行之间生成的笛卡尔积。GENERATE 使用两个表表达式:

GENERATE
  1. GENERATE ( <Table1>, <Table2> )
复制代码
参数属性描述
Table1GENERATE 使用的基础表.
Table2在 Table1 的每一行计值的表表达式

GENERATEALL
  1. GENERATEALL(<Table1>, <Table2>)
复制代码
参数属性描述
Table1GENERATEALL 使用的基础表.
Table2在 Table1 的每一行计值的表表达式


GENERATEALL 与 GENERATE 的计值过程相同,仅在对空行的处理上有所区别。当对<Table2>的计算返回空记录时,GENERATEALL 将来自<Table1>的当前行包含在结果中。这与 GENERATE 不同,后者移除所有空值对应的<Table1>当前行。


另外,与 CROSSJOIN 类似,GENERATE 系列函数的 Table1 和 Table2 中的所有列名不能有重复,否则将报错。

示例用法

GENERATE 的一个简单用法是生成包含产品类别和子类别的所有有效组合的表,你可以使用这个查询
  1. EVALUATE
  2. GENERATE (
  3.     'Product Category',
  4.     RELATEDTABLE ( 'Product Subcategory' )
  5. )
复制代码


7060211939331.jpeg



GENERATE 调用的 Table2 通常包含 RELATEDTABLECALCULATETABLE 函数,以便使用 Table1 迭代的行上下文进行上下文转换
如果在第二参数中省略 RELATEDTABLE,将得到与 CROSSJOIN 相同的结果,因为没有通过 RELATEDTABLE 将行上下文转换筛选上下文,(RELATEDTABLE 是 CALCULATEDTABLE 简化版的别名)

实际上,以下查询是等效的:
  1. EVALUATE
  2. GENERATE( 'Product Category', 'Product Subcategory' )

  3. EVALUATE
  4. CROSSJOIN( 'Product Category', 'Product Subcategory' )
复制代码

GENERATE 的一个更有趣的例子是如何得到一个表,使其包含每年销售量排名前两位的产品。以下查询对每一年执行 TOPN 函数,计算每一年中对应产品的排名:
  1. EVALUATE
  2. GENERATE (
  3.     VALUES ( 'Date'[Calendar Year] ),
  4.     TOPN (
  5.         2,
  6.         SUMMARIZE (
  7.             RELATEDTABLE ( Sales ),
  8.             Product[Product Name]
  9.         ),
  10.         CALCULATE (
  11.             SUM ( Sales[Quantity] )
  12.         )
  13.     )
  14. )
复制代码


7060211939332.jpeg



这里需要注意的是,查询只返回那些至少包含一笔销售记录的年份。如果你还希望在销售表中包含没有任何销售记录的年份,可以使用 GENERATEALL 代替 GENERATE,如以下查询所示:
  1. EVALUATE
  2. GENERATEALL (
  3.     VALUES ( 'Date'[Calendar Year] ),
  4.     TOPN (
  5.         2,
  6.         SUMMARIZE (
  7.             RELATEDTABLE ( Sales ),
  8.             Product[Product Name]
  9.         ),
  10.         CALCULATE (
  11.             SUM ( Sales[Quantity] )
  12.         )
  13.     )
  14. )
复制代码


7060211939333.jpeg



如果你习惯使用 SQL,你可以认为 GENERATE 函数类似于 SQL 中的 CROSS APPLY 条件,而 GENERATEALL 函数类似于 SQL 中的 OUTER APPLY 条件
回复

使用道具 举报

find-ok | 2021-4-24 12:24:49 来自手机 | 显示全部楼层
为毛老子总也抢不到沙发?!!
回复

使用道具 举报

自由 | 2021-6-12 14:12:41 | 显示全部楼层
前排,哇咔咔
回复

使用道具 举报

奔奔兔 | 2021-7-12 14:25:56 | 显示全部楼层
看帖要回,回帖才健康,在踩踩,楼主辛苦了!
回复

使用道具 举报

lzw | 2021-7-13 07:06:55 | 显示全部楼层
专业抢沙发的!哈哈
回复

使用道具 举报

fivemeteor | 2021-8-2 07:09:26 | 显示全部楼层
顶顶更健康
回复

使用道具 举报

coke仔 | 2021-8-6 09:56:34 来自手机 | 显示全部楼层
我了个去,顶了
回复

使用道具 举报

xieshaoning | 2021-8-15 09:33:54 来自手机 | 显示全部楼层
报告!别开枪,我就是路过来看看的。。。
回复

使用道具 举报

牛屎仔 | 2021-8-27 20:47:03 来自手机 | 显示全部楼层
有空一起交流一下
回复

使用道具 举报

妹头 | 2021-8-30 07:37:05 来自手机 | 显示全部楼层
不错 支持一个了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则