You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将实现递归间隔筛选的TSQL代码转换为DAX?

将递归筛选时间间隔的TSQL转换为DAX实现

可以实现该逻辑的DAX转换。DAX虽然没有原生递归CTE,但可以通过迭代变量和递推逻辑模拟原TSQL的行为——为每个ID提取最早时间后,依次查找下一个与上一条选中记录间隔≥15分钟的最早时间。

实现代码

筛选后时间表 = 
VAR AllIDs = VALUES(example[ID])
RETURN
    GENERATE(
        AllIDs,
        VAR CurrentID = [ID]
        // 获取当前ID的所有时间并按升序排序
        VAR SortedTimes = 
            SORT(
                CALCULATETABLE(VALUES(example[DTTM]), example[ID] = CurrentID),
                [DTTM], ASC
            )
        // 初始选中:每个ID的最早时间
        VAR SelectedTimes = {MINX(SortedTimes, [DTTM])}

        // 第一次递归:查找第一个符合间隔条件的时间
        VAR Selected1 = 
            VAR LastSelected = LASTNONBLANK(SelectedTimes, [DTTM])
            VAR NextTime = 
                MINX(
                    FILTER(SortedTimes, [DTTM] >= LastSelected + TIME(0, 15, 0)),
                    [DTTM]
                )
            RETURN
                IF(NOT ISBLANK(NextTime), UNION(SelectedTimes, {NextTime}), SelectedTimes)

        // 第二次递归:查找下一个符合条件的时间
        VAR Selected2 = 
            VAR LastSelected = LASTNONBLANK(Selected1, [DTTM])
            VAR NextTime = 
                MINX(
                    FILTER(
                        SortedTimes,
                        [DTTM] >= LastSelected + TIME(0, 15, 0) &&
                        NOT CONTAINS(Selected1, [DTTM], [DTTM])
                    ),
                    [DTTM]
                )
            RETURN
                IF(NOT ISBLANK(NextTime), UNION(Selected1, {NextTime}), Selected1)

        // 第三次递归:查找下一个符合条件的时间
        VAR Selected3 = 
            VAR LastSelected = LASTNONBLANK(Selected2, [DTTM])
            VAR NextTime = 
                MINX(
                    FILTER(
                        SortedTimes,
                        [DTTM] >= LastSelected + TIME(0, 15, 0) &&
                        NOT CONTAINS(Selected2, [DTTM], [DTTM])
                    ),
                    [DTTM]
                )
            RETURN
                IF(NOT ISBLANK(NextTime), UNION(Selected2, {NextTime}), Selected2)

        // 第四次递归(若数据需要更多层级,可继续添加)
        VAR Selected4 = 
            VAR LastSelected = LASTNONBLANK(Selected3, [DTTM])
            VAR NextTime = 
                MINX(
                    FILTER(
                        SortedTimes,
                        [DTTM] >= LastSelected + TIME(0, 15, 0) &&
                        NOT CONTAINS(Selected3, [DTTM], [DTTM])
                    ),
                    [DTTM]
                )
            RETURN
                IF(NOT ISBLANK(NextTime), UNION(Selected3, {NextTime}), Selected3)

        RETURN
            // 将选中的时间转换为包含ID和DTTM的表
            SELECTCOLUMNS(
                Selected4,
                "ID", CurrentID,
                "DTTM", [DTTM]
            )
    )
// 对最终结果排序
ORDER BY [ID], [DTTM]

逻辑说明

  1. 分组处理:通过AllIDs和GENERATE为每个ID单独处理时间筛选,确保逻辑按ID隔离。
  2. 初始选中:先获取每个ID的最早时间,对应TSQL递归CTE的锚点成员。
  3. 递推筛选:每一层SelectedN变量以上一层选中的最后一个时间为基准,查找当前ID中满足「晚于上一个选中时间≥15分钟」的最早时间,若找到则合并到选中列表中,对应TSQL的递归成员。
  4. 结果输出:将选中的时间转换为标准表结构并排序,与原TSQL的最终查询逻辑一致。

扩展说明

如果你的数据需要更多层级的递归(即需要多次查找符合条件的时间),只需按照现有SelectedN的格式继续添加迭代层级即可。

内容的提问来源于stack exchange,提问作者Oded Dror

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:05:54