From b6146429531ca59919da1f7fc337ad49316c2ee7 Mon Sep 17 00:00:00 2001 From: lingxin <961347548@qq.com> Date: Mon, 17 Mar 2025 10:12:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96count=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lxDb/sql.go | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/lxDb/sql.go b/lxDb/sql.go index 6b4cf11..2945aa6 100644 --- a/lxDb/sql.go +++ b/lxDb/sql.go @@ -214,6 +214,95 @@ func SqlQuery(tx *gorm.DB, sql string, list interface{}, q *PaginationQuery, par params = make([]interface{}, 0) } + // 条件字段 + if q != nil { + where, args := q.BuildRawWhere() + if hasWhere(sql) { // 原SQL已有WHERE子句 + builder.WriteString(where) // 去掉where 前头的and or .. + } else { // 原SQL没有WHERE子句 + if strings.HasPrefix(where, " AND ") { + where = strings.Replace(where, " AND ", " WHERE ", 1) + builder.WriteString(where) + } else if strings.HasPrefix(where, " OR ") { + where = strings.Replace(where, " OR ", " WHERE ", 1) + builder.WriteString(where) + } else { + builder.WriteString(where) // "" 或者 " GROUP BY ..." + } + } + if len(args) > 0 { + params = append(params, args...) + } + + // 半成品 sql 用于查询其他信息 + var sql2 = builder.String() + + // 记录条数 + if needDoCount(q) { + var total int64 + //tx = tx.Count(&total) + tx.Raw("SELECT COUNT(*) as total FROM ("+sql2+") aaaa", params...).Take(&total) + q.Total = int(total) + if total == 0 { // 如果查了记录条数并且是0, 就不需要查记录和汇总了 + return + } + + // 获取汇总信息 // TODO: 汇总应该放到查询列表的后面 + if q.Summary != "" && len(q.SummarySql) == 0 { + q.SummarySql = fieldsToSumSql(q.Summary) + } + if len(q.Summary) != 0 { + tx = tx.Offset(-1) // 需要去除offset, 否则结果可能为空, 注意: 设置0不起作用. + var summary = make(map[string]interface{}) + //tx.Order("") // FIXME: 怎么去掉order by, sum是不需要order by的, 影响性能. + //tx.Select(q.SummarySql).Take(&summary) // 不适合rawsql? + + tx.Raw("SELECT "+strings.Join(q.SummarySql, ", ")+" FROM ("+sql2+") ssss", params...).Take(&summary) + + // []byte 转 string. 不太合理, 应该返回int或float + for k, v := range summary { + if bs, ok := v.([]byte); ok { + summary[k] = string(bs) + } + } + q.SummaryResult = summary + } + } + + // 排序处理 + if q.OrderBy != "" { + s := fmt.Sprintf(" ORDER BY %s", lxUtil.FieldToColumn(q.OrderBy)) // TODO: q.OrderBy是字符串,可能多个字段 会有问题吗 + builder.WriteString(s) + } + + // 偏移量处理 + if q.Limit > 0 { + if q.Offset > 0 { + offset := (q.Offset - 1) * q.Limit + s := fmt.Sprintf(" LIMIT %d, %d", offset, q.Limit) + builder.WriteString(s) + } else { + s := fmt.Sprintf(" LIMIT %d", q.Limit) + builder.WriteString(s) + } + } + } + + //tx.Raw(builder.String(), params...).Scan(list) // FIXME: unsupported data type: &[] why? + tx.Raw(builder.String(), params...).Find(list) // Find与Scan区别: list传入[]时, 查询为空的情况下, Find返回的是[], 而Scan返回的是nil. + // ref: What is the difference between Find and Scan: https://github.com/go-gorm/gorm/issues/4218 + + return +} + +func SqlQueryNew(tx *gorm.DB, sql string, list interface{}, q *PaginationQuery, params ...interface{}) (err error) { + var builder strings.Builder + builder.WriteString(sql) + + if params == nil { + params = make([]interface{}, 0) + } + // 条件字段 if q != nil { where, args := q.BuildRawWhere() @@ -417,7 +506,7 @@ func replaceSelectAndRemoveGroupBy(sql string) string { replacedSQL := sql[:selectIndex+6] + " " + newSelectClause + " " + sql[fromIndex:] // 去掉 GROUP BY 子句 - groupByIndex := strings.Index(strings.ToUpper(replacedSQL), "GROUP BY") + groupByIndex := strings.LastIndex(strings.ToUpper(replacedSQL), "GROUP BY") if groupByIndex != -1 { c := replacedSQL[groupByIndex+8:] c = strings.TrimSpace(c)