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

如何将带子查询的SQL转为Drift语法(无需自定义查询)及子查询位置

将目标SQL转换为Drift语法的实现

原SQL逻辑拆解

原SQL通过两次左连接实现:先分组activities拿到每个tracker的最新活动结束时间,再关联trackers表,最后通过子查询结果匹配到对应的最新活动记录。

Drift代码改造(含子查询位置)

子查询需要作为第一个关联项,放在trackers和activities的连接之间,完整代码如下:

// 1. 构建原SQL中的子查询:获取每个tracker的最新活动结束时间
final subquery = selectOnly(activities)
  ..addColumns([
    activities.tracker,
    activities.end.max().alias('latest_activity_date'),
  ])
  ..groupBy([activities.tracker]);

// 2. 主查询:依次关联trackers、子查询、activities
final query = select(trackers).join([
  // 第一步左连接子查询,对应原SQL的第一个LEFT JOIN
  leftOuterJoin(
    subquery.as('subquery'),
    subquery['tracker'].equalsExp(trackers.id),
  ),
  // 第二步左连接activities,对应原SQL的第二个LEFT JOIN
  leftOuterJoin(
    activities,
    activities.tracker.equalsExp(subquery['tracker']) &
        activities.end.equalsExp(subquery['latest_activity_date']),
  ),
])
  // 对应原SQL的ORDER BY a."end"
  ..orderBy([OrderingTerm.desc(activities.end)]);

// 执行查询并转换结果
query.get().then((rows) => rows.map((row) {
      final tracker = row.readTable(trackers);
      // 左连接可能返回null,用readTableOrNull更严谨
      final latestActivity = row.readTableOrNull(activities);
      return TrackerWithLatestActivity(tracker, latestActivity);
    }).toList());

关键说明

  • 子查询通过selectOnly构建,只选择需要的字段,用.max()聚合函数实现MAX(activities."end"),.alias()对应SQL中的字段别名。
  • 主查询的join顺序严格对应原SQL:先关联trackers和子查询,再通过子查询的结果关联到对应的最新activities记录。
  • 因为是左连接,activities可能没有匹配记录,所以用readTableOrNull替代readTable避免空指针问题。

内容的提问来源于stack exchange,提问作者Bang Dida

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:36:18