Gorm Join查询时聚合函数查询结果被强制置为[]unit的解决

111 阅读1分钟

默认使用Grom Join查询的方法

官网 gorm.io/zh_CN/docs/…

使用Raw.Rows

SQL较为复杂,使用Raw原生SQL查询

var results []model.InstanceBillItemsUsage
var cost_unit string
var CostUnitSum float32
var TotalSum float32
var Percentage []uint

rows,err := aliDB.Db.Raw("SELECT cost_unit, SUM(pretax_amount) AS CostUnitSum,totals.TotalSum, CONCAT(FORMAT((SUM(pretax_amount) / totals.TotalSum) * 100, 2), '%') AS Percentage FROM instance_bill_items_usages JOIN (  SELECT SUM(pretax_amount) AS TotalSum   FROM instance_bill_items_usages WHERE billing_date BETWEEN ? AND ? ) AS totals WHERE  instance_bill_items_usages.billing_date BETWEEN ? AND ? GROUP BY  cost_unit; ", startDate, endDate, startDate, endDate).
    WithContext(aliDB.Ctx).Rows

 defer rows.Close()

 for rows.Next() {
   rows.Scan(&cost_unit, &CostUnitSum, &TotalSum, &Percentage)

   fmt.Println(results)
 }

 if err != nil {
  fmt.Println(err)
 }

但缺点是,像以上 totals.TotalSum 会被转换为 []uint8 类型是因为在某些情况下,数据库驱动返回的聚合函数结果(如 SUM、COUNT、AVG)可能以字节流形式返回,特别是在使用 GORM 进行查询时。[]uint8 实际上就是 Go 语言中的字节切片,对应于 SQL 查询结果中的 BLOB 或 TEXT 类型数据。

方法2 使用.Scan直接扫描

在 GORM 里处理这种情况的一种方法是,将该字段显式地扫描到正确的 Go 类型。例如,如果你期望 TotalSum 是一个 float64 类型的值,可以在 GORM 查询后使用 .Scan 方法将查询结果扫描到一个结构体或者变量中,且该结构体或变量中的字段具有期望的类型。

即可实现强制指定扫描类型


  type Result struct {
    CostUnit   string  `gorm:"column:cost_unit"`
    GroupSum   float64 `gorm:"column:GroupSum"`
    TotalSum   float64 `gorm:"column:TotalSum"`
    Percentage string  `gorm:"column:Percentage"`
  }

  var results []Result

  aliDB.Db.Raw("SELECT cost_unit, SUM(pretax_amount) AS CostUnitSum,totals.TotalSum, CONCAT(FORMAT((SUM(pretax_amount) / totals.TotalSum) * 100, 2), '%') AS Percentage FROM instance_bill_items_usages JOIN (  SELECT SUM(pretax_amount) AS TotalSum   FROM instance_bill_items_usages WHERE billing_date BETWEEN ? AND ? ) AS totals WHERE  instance_bill_items_usages.billing_date BETWEEN ? AND ? GROUP BY  cost_unit; ", startDate, endDate, startDate, endDate).
    WithContext(aliDB.Ctx).Scan(&results)

  fmt.Println(results)