Sequelize 是一个 Node.js 的 ORM(Object Relational Mapping)工具,可以方便地操作数据库,大大简化了前端开发者对数据库的操作。在使用 Sequelize 进行查询时,很多情况下需要进行分组操作,本文将详细介绍如何使用 Sequelize 进行分组查询。
什么是分组查询
分组查询是在查询数据时将数据分组,然后进行聚合操作,例如求某一组的最大、最小、平均值等。分组查询在业务逻辑中非常常见,例如 eCommerce 中查询每个商品的销售数量,社交媒体中查询用户每天的活跃度等。
Sequelize 分组查询的基本用法
Sequelize 对于分组查询提供了 sequelize.fn()
和 sequelize.literal()
两个函数来实现 SQL 函数的使用。其中,sequelize.fn()
可以用来构造函数,例如调用 sequelize.fn('SUM', sequelize.col('price'))
将会生成 SUM(price)
,而 sequelize.literal()
可以用于直接拼接字符串,例如调用 sequelize.literal('COUNT(*)')
将会生成 COUNT(*)
。
下面是一个简单的例子,在 Order
表中按照 productId
进行分组,查询每个 productId
的平均价格:
-- -------------------- ---- ------- ----- - ---------- --------- - - --------------------- ----- ----- - ------------------------- - --- - ----- ------------------ ----------- ----- -------------- ----- -- ---------- - ----- ------------------ ---------- ------ -- ------ - ----- ---------------- ---------- ------ -- --- ------ ---------- - ----- ----------------- ----- ------ - ----- --------------- ----------- ------------- -------------------- ------------------------ ------------- ------ -------------- --- -------------------- -----
在这个例子中,我们使用了 sequelize.fn()
来构造 AVG(price)
函数得到每个 productId
的平均价格。同时,我们还使用了 group
来指定按照 productId
进行分组。最后,我们使用 console.log(result)
来将查询的结果输出。
Sequelize 分组查询的进阶用法
在 Sequelize 中,分组查询还提供了一些进阶用法,包括:
- 分组条件过滤:
分组查询默认会返回所有分组,但是我们可以使用 having
参数来指定分组条件。例如,我们可以在上面的例子中加上 having: sequelize.where(sequelize.fn('AVG', sequelize.col('price')), '>', 10)
来只查询平均价格大于 10 的商品。
const result = await Order.findAll({ attributes: ['productId', [sequelize.fn('AVG', sequelize.col('price')), 'avgPrice']], group: ['productId'], having: sequelize.where(sequelize.fn('AVG', sequelize.col('price')), '>', 10), });
- 多个聚合函数查询:
除了基本用法中的单个聚合函数,我们还可以在一个查询语句中进行多次计算。例如,我们可以查询每个 productId
的平均价格和最低价格:
const result = await Order.findAll({ attributes: ['productId', [sequelize.fn('AVG', sequelize.col('price')), 'avgPrice'], [sequelize.fn('MIN', sequelize.col('price')), 'minPrice']], group: ['productId'], });
在这里,我们使用了 sequelize.fn()
来同时计算 AVG(price)
和 MIN(price)
。需要注意的是,在返回结果中,每个 productId
对应的 avgPrice
和 minPrice
都需要在 attributes
中进行定义。
- 多个分组字段查询:
我们可以使用数组来指定多个分组字段。例如,我们可以按照每个 productId
和 userId
进行分组,查询每个 productId
和 userId
下的订单总数:
const result = await Order.findAll({ attributes: ['productId', 'userId', [sequelize.fn('COUNT', sequelize.col('id')), 'count']], group: ['productId', 'userId'], });
在这里,我们使用了两个分组字段 productId
和 userId
,以及 AVG(price)
函数来得到每个 productId
和 userId
下的订单总数。需要注意的是,在返回结果中,每个 (productId, userId)
对应的 count
都需要在 attributes
中进行定义。
总结
本文介绍了 Sequelize 进行分组查询的基本用法和进阶用法。使用 Sequelize 进行分组查询可以方便地得到数据库中的聚合数据,是前端开发中不可或缺的技术手段。在学习 Sequelize 的过程中,学会使用分组查询将会大大提升查询的效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647aae94968c7c53b065b55e