全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-21 8 分钟 ✍️ juanwangdev

GORM 子查询实现

本文介绍 GORM 中子查询的构建方式及其在复杂查询中的应用。

SubQuery 方法

基本用法

将子查询结果作为条件或字段嵌入主查询。

Go
// 子查询作为字段
subQuery := db.Table("orders").Select("AVG(amount)").Where("user_id = users.id")
db.Model(&User{}).Select("*, (?) AS avg_order", subQuery).Find(&users)

// 子查询作为条件
subQuery := db.Table("orders").Select("user_id").Where("amount > ?", 100)
db.Where("id IN (?)", subQuery).Find(&users)

语法格式:

Go
subQuery := db.Table("表名").Select("字段").Where("条件")
db.Where("字段 IN (?)", subQuery).Find(&results)

WHERE 子句中的子查询

Go
// IN 子查询
subQuery := db.Table("orders").Select("user_id").Where("status = ?", "completed")
db.Where("id IN (?)", subQuery).Find(&users)

// NOT IN 子查询
subQuery := db.Table("banned_users").Select("user_id")
db.Where("id NOT IN (?)", subQuery).Find(&users)

// EXISTS 子查询
subQuery := db.Table("orders").Select("1").Where("user_id = users.id AND amount > ?", 500)
db.Where("EXISTS (?)", subQuery).Find(&users)

SELECT 子句中的子查询

Go
// 标量子查询作为字段
orderCount := db.Table("orders").Select("COUNT(*)").Where("user_id = users.id")
db.Model(&User{}).Select("*, (?) AS order_count", orderCount).Find(&users)

avgAmount := db.Table("orders").Select("AVG(amount)").Where("user_id = users.id")
db.Model(&User{}).Select("*, (?) AS avg_amount", avgAmount).Find(&users)

FROM 子句中的子查询

Go
// 子查询作为派生表
subQuery := db.Table("orders").Select("user_id, SUM(amount) as total").Group("user_id")
db.Table("(?) AS u", subQuery).Find(&results)

// 复杂嵌套
subQuery := db.Table("orders").Select("user_id, COUNT(*) as cnt").Group("user_id").Where("cnt > ?", 5)
db.Table("(?) AS frequent_buyers", subQuery).Joins("JOIN users ON users.id = frequent_buyers.user_id").Find(&users)

嵌套子查询

Go
// 多层嵌套
innerQuery := db.Table("order_items").Select("order_id").Where("price > ?", 100)
middleQuery := db.Table("orders").Select("user_id").Where("id IN (?)", innerQuery)
db.Where("id IN (?)", middleQuery).Find(&users)

注意事项

  1. 子查询中 ? 占位符自动包裹括号,无需手动添加 ()
  2. 作为字段的标量子查询需确保只返回单个值,否则可能报错。
  3. 深层嵌套子查询可读性差,可考虑使用临时表或分步查询替代。
  4. 子查询性能不如 JOIN 时,优先评估数据量和索引情况。

要点总结

  • SubQuery 方法返回 *gorm.SubQuery 类型,可直接嵌入主查询。
  • WHERE 子查询常用 IN/NOT IN/EXISTS 语法实现条件过滤。
  • SELECT 子查询用于添加计算字段。
  • FROM 子查询将子查询结果作为临时表使用。
  • 子查询嵌套层数过多时,考虑使用 JOIN 或分步查询优化可读性与性能。

存放路径:D:\git2\jwdev\articles\GORM\进阶\高级查询技术\子查询实现.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 GORM 原生 SQL 执行
下一篇 → GORM 链式查询详解
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库