You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go/GORM中如何使用between条件查询int64类型字段

GORM 针对int64类型字段实现Between范围查询方案

你的created_at字段用bigint存时间戳,做between查询不需要额外类型转换,GORM支持直接拼接条件,具体实现步骤如下:

1. 先调整查询参数结构体

你原来的Project结构体只有单值CreatedAt字段,无法接收前端传的起止时间/时间数组,需要单独定义列表查询的请求参数结构,兼容两种前端传参格式:

import "strconv"

// 项目列表查询请求参数
type ProjectListReq struct {
    Page           int      `json:"page"`
    PageSize       int      `json:"page_size"`
    Email          string   `json:"email"`
    CreatedAtSt    int64    `json:"create_at_st"`  // 起始时间戳 对应第一种传参格式
    CreatedAtEnd   int64    `json:"create_at_end"` // 结束时间戳 对应第一种传参格式
    CreatedAtRange []string `json:"create_at"`     // 时间范围数组 对应第二种传参格式
}

2. Between条件的两种GORM写法

两种写法最终生成的SQL执行效果完全一致,选你觉得好维护的用就行:

  • 直接写原生Between语法,和你预期的SQL完全匹配:
db = db.Where("created_at BETWEEN ? AND ?", 起始时间戳, 结束时间戳)
  • 用大于等于+小于等于条件拼接,逻辑和Between等价:
db = db.Where("created_at >= ?", 起始时间戳).Where("created_at <= ?", 结束时间戳)

3. 完整改造后的查询方法

你原来的代码存在几个问题:未定义db/List/total变量、Count查询带了分页参数会导致总数统计错误、原有created_at <> ?是不等于逻辑和范围查询无关需要删除,改造后代码如下:

func (p *Project) ProjectList(req ProjectListReq) ([]Project, int64, error) {
    var list []Project
    var total int64
    // 初始化DB实例 替换成你项目里的gorm DB对象
    db := gorm.Model(&Project{})

    // 拼接邮箱模糊查询条件
    if req.Email != "" {
        db = db.Where("email LIKE ?", "%"+req.Email+"%")
    }

    // 拼接时间范围条件 优先处理起止时间参数
    if req.CreatedAtSt != 0 && req.CreatedAtEnd != 0 && req.CreatedAtEnd > req.CreatedAtSt {
        db = db.Where("created_at BETWEEN ? AND ?", req.CreatedAtSt, req.CreatedAtEnd)
    } else if len(req.CreatedAtRange) == 2 {
        // 兼容数组格式传参 先把字符串时间戳转成int64
        st, errSt := strconv.ParseInt(req.CreatedAtRange[0], 10, 64)
        ed, errEd := strconv.ParseInt(req.CreatedAtRange[1], 10, 64)
        if errSt == nil && errEd == nil && ed > st {
            db = db.Where("created_at BETWEEN ? AND ?", st, ed)
        }
    }

    // 先查总数 克隆DB对象避免分页参数影响count结果
    countTx := db.Session(&gorm.Session{})
    if err := countTx.Count(&total).Error; err != nil {
        return nil, 0, err
    }

    // 拼接分页、排序参数查列表
    err := db.Offset((req.Page - 1) * req.PageSize).
        Limit(req.PageSize).
        Order("id DESC").
        Find(&list).Error

    return list, total, err
}

注意事项

  • 时间参数要做合法性校验:结束时间必须大于起始时间,避免生成无效条件查不到数据
  • Count查询必须在拼接分页参数之前执行,或者克隆新的DB对象执行,否则Offset/Limit会被带到count SQL里导致总数统计错误
  • 因为字段本身是int64类型,直接传int64值给GORM即可,不需要做时间格式转换,不会出现类型不匹配问题

内容的提问来源于stack exchange,提问作者Elsa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 03:09:44