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

Sequelize非原生查询实现:如何统计子查询结果

用Sequelize实现目标查询的两种方案

方案一:简化写法(和原SQL逻辑等价)

你的SQL本质是统计至少有一个地址的客户总数,用INNER JOIN加distinct参数就能直接实现,代码更简洁:

const { Op } = require('sequelize');
const Client = require('../models/Client'); // 替换成你的Client模型路径
const ClientAddress = require('../models/ClientAddress'); // 替换成你的ClientAddress模型路径

const clientCount = await Client.count({
  include: [{
    model: ClientAddress,
    required: true, // 用INNER JOIN自动过滤无地址的客户
    attributes: [] // 不需要返回地址表字段
  }],
  distinct: true, // 保证每个客户只被统计一次
  attributes: ['id'] // 基于客户ID去重统计
});

方案二:严格匹配原嵌套查询结构

如果需要完全复刻原SQL的嵌套子查询写法,可以用Sequelize的子查询功能实现:

const { Op, fn, col, where } = require('sequelize');
const Client = require('../models/Client');
const ClientAddress = require('../models/ClientAddress');

// 构建子查询:获取所有有地址的客户ID
const subQuery = Client.findAll({
  attributes: ['id'],
  include: [{
    model: ClientAddress,
    attributes: [],
    required: false // 对应原SQL的LEFT OUTER JOIN
  }],
  group: ['clients.id'],
  having: where(fn('COUNT', col('client_addresses.id')), '>', 0),
  raw: true
});

// 外层查询:统计子查询结果的数量
const clientCount = await Client.count({
  where: {
    id: {
      [Op.in]: subQuery
    }
  }
});

注意事项

  • 要先正确定义模型关联:Client.hasMany(ClientAddress, { foreignKey: 'client_id' })
  • fn用来调用SQL聚合函数,col指定表字段,避免字段名冲突
  • required: false对应原SQL的LEFT OUTER JOIN,required: true则是INNER JOIN

内容的提问来源于stack exchange,提问作者Erick Avalos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:49:54