gen icon indicating copy to clipboard operation
gen copied to clipboard

子查询可以作为一个field使用吗?没有找到相关用法

Open m430 opened this issue 2 years ago • 5 comments

Your Question

比如我有一个班级表,还有一个学生表,需要查询出班级中学生个数。

c := query.Class
s := query.Student

// 这里查询学生个数
sub := s.WithContext(ctx).Select(s.ALL.Count()).Where(s.ClassID.EqCol(c.ID))

// 这里想用一个子查询直接作为一个Field进行查询返回
c.WithContext(ctx).Select(c.ALL, sub.As("student_num")).Find()

目前不支持这个操作,有什么办法吗?这个应该属于比较常见的用法吧

希望可以支持field.NewSubQuery类似这样的方法。目前动态属性没办法使用子查询。

@riverchu

m430 avatar Jul 17 '23 07:07 m430

这个吧.

func NewSubQuery(db *gorm.DB) Field {
	return Field{
		expr{
			e: clause.Expr{
				SQL:  "(?)",
				Vars: []any{db},
			},
		},
	}
}

或者还得加个这个

// NewRaw new raw
func NewRaw(sql string, vars ...any) Field {
	return Field{
		expr{
			e: clause.Expr{
				SQL:                sql,
				Vars:               vars,
				WithoutParentheses: false,
			},
		},
	}
}

thinkgos avatar Jul 28 '23 07:07 thinkgos

没有找到这个代码

a67793581 avatar Oct 07 '23 12:10 a67793581

NewRaw

没有找到这个代码

a67793581 avatar Oct 07 '23 12:10 a67793581

+1 也没有找到生成下面语句的方式

SELECT `t1`.*,
       (SELECT COUNT(*) FROM `t2` WHERE `t1`.`app_id` = `t2`.`app_id`) AS `filed1`
FROM `t1`
WHERE `t1`.`deleted_at` IS NULL
LIMIT 10

mozhu811 avatar Nov 21 '23 21:11 mozhu811

目前找到这样的解决方法,不知道是否还有更加好的办法?

func (r *AppRepo) List(ctx context.Context, page uint32, pageSize uint32) (apps []*cond.AppBase, total int64, err error) {
	q := query.Use(r.db)
	appDao := q.App
	appStarDao := q.AppStar
	starSubQuery := r.db.WithContext(ctx).Table(appStarDao.TableName()).
		Select("COUNT(*)").
		Where("`app_star`.`app_id` = `app`.`app_id`")
	err = r.db.WithContext(ctx).Table(appDao.TableName()).
		Select("`app`.*, (?) AS `stars`", starSubQuery).
		Limit(int(pageSize)).
		Offset(int(pageSize * (page - 1))).
		Scan(&apps).Error

	return
}
 SELECT `app`.*, (SELECT COUNT(*) FROM `app_star` WHERE `app_star`.`app_id` = `app`.`app_id`) AS `stars` FROM `app` LIMIT 10

mozhu811 avatar Nov 22 '23 07:11 mozhu811