将SQL中的Having子句转换为DAX的技术求助
SQL转DAX:处理HAVING子句的解决方案
原SQL逻辑回顾
你的SQL是要筛选G_Space表中满足以下条件的数据:
PropertyCode = 30500、rank = 1、Leaseid非空period在201807到当前年月之间
按PropertyCode和UnitCode分组后,仅保留最大period小于当前年月的组,最终返回每组的编码,以及将最大period转为当月第一天的lastoccupied日期。
你的DAX问题分析
你写的计算列已经实现了分组取最大period的逻辑,但漏掉了原SQL的rank=1条件,且不知道如何对应SQL里的HAVING子句——DAX没有直接的HAVING语法,需要通过筛选聚合结果来实现相同逻辑。
修正后的计算列DAX
= VAR Min_Period = 201807 VAR Current_Period = VALUE(FORMAT(TODAY(), "YYYYMM")) VAR Current_Property = Space[PropertyCode] VAR Current_Unit = Space[Unit Code] -- 计算当前Property+Unit组的最大period,同时补上原SQL的rank=1条件 VAR Max_Period = CALCULATE( MAX(Space[Period]), FILTER( Space, Space[PropertyCode] = Current_Property && Space[Unit Code] = Current_Unit && Space[Period] >= Min_Period && Space[Period] <= Current_Period && NOT(ISBLANK(Space[Leaseid])) && Space[rank] = 1 ) ) -- 用IF实现HAVING逻辑:仅当最大period小于当前年月时返回转换后的日期,否则返回空 RETURN IF( Max_Period < Current_Period, DATE(LEFT(Max_Period, 4), RIGHT(Max_Period, 2), 1), BLANK() )
关键调整说明
- 补上遗漏的
rank=1条件:原SQL的WHERE子句包含该条件,你的DAX里漏掉了,必须加上才能和SQL结果一致。 - 简化当前年月计算:用
FORMAT(TODAY(), "YYYYMM")直接生成年月字符串再转数值,比原写法更简洁可靠。 - 实现HAVING逻辑:通过
IF判断聚合后的Max_Period是否小于Current_Period,满足则返回转换后的日期,否则返回空(相当于过滤掉不满足条件的组)。 - 更可靠的日期转换:用
DATE函数直接拆分年月生成日期,避免字符串拼接可能出现的格式问题。
如果你需要返回完整结果表(而非计算列)
如果要直接生成和SQL查询结果一致的表,可以用SUMMARIZECOLUMNS配合外部筛选实现,更贴近SQL的分组逻辑:
LastOccupiedTable = VAR Min_Period = 201807 VAR Current_Period = VALUE(FORMAT(TODAY(), "YYYYMM")) RETURN FILTER( SUMMARIZECOLUMNS( Space[PropertyCode], Space[Unit Code], -- 定义聚合字段 "Max_Period", MAX(Space[Period]), "lastoccupied", DATE(LEFT(MAX(Space[Period]), 4), RIGHT(MAX(Space[Period]), 2), 1), -- 对应SQL的WHERE条件 FILTER( Space, Space[rank] = 1 && NOT(ISBLANK(Space[Leaseid])) && Space[Period] >= Min_Period && Space[Period] <= Current_Period && Space[PropertyCode] = 30500 ) ), -- 对应SQL的HAVING子句:筛选聚合后的结果 [Max_Period] < Current_Period )
注:表的排序可以在可视化工具中直接设置按lastoccupied排序,无需在DAX中硬编码。
内容的提问来源于stack exchange,提问作者Molefe Boikanyo
相关产品推荐
相关产品推荐

