- Created by 郭强, last modified on May 25, 2022
LeftJoin/RightJoin/InnerJoin
LeftJoin
左关联查询;RightJoin
右关联查询;InnerJoin
内关联查询;
其实我们并不推荐使用Join
进行联表查询,特别是在数据量比较大、并发请求量比较高的场景中,容易产生性能问题,也容易提高维护的复杂度。建议您在确定有此必要的场景下使用。此外,您也可以参考 ORM链式操作-模型关联 章节,数据库只负责存储数据和简单的单表操作,通过ORM
提供的功能在代码层面实现数据聚合。
使用示例:
// 查询符合条件的单条记录(第一条) // SELECT u.*,ud.site FROM user u LEFT JOIN user_detail ud ON u.uid=ud.uid WHERE u.uid=1 LIMIT 1 g.Model("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.site").Where("u.uid", 1).One() // 查询指定字段值 // SELECT ud.site FROM user u RIGHT JOIN user_detail ud ON u.uid=ud.uid WHERE u.uid=1 LIMIT 1 g.Model("user u").RightJoin("user_detail ud", "u.uid=ud.uid").Fields("ud.site").Where("u.uid", 1).Value() // 分组及排序 // SELECT u.*,ud.city FROM user u INNER JOIN user_detail ud ON u.uid=ud.uid GROUP BY city ORDER BY register_time asc g.Model("user u").InnerJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.city").Group("city").Order("register_time asc").All() // 不使用join的联表查询 // SELECT u.*,ud.city FROM user u,user_detail ud WHERE u.uid=ud.uid g.Model("user u,user_detail ud").Where("u.uid=ud.uid").Fields("u.*,ud.city").All()
自定义数据表别名
// SELECT * FROM `user` AS u LEFT JOIN `user_detail` as ud ON(ud.id=u.id) WHERE u.id=1 LIMIT 1 g.Model("user", "u").LeftJoin("user_detail", "ud", "ud.id=u.id").Where("u.id", 1).One() g.Model("user").As("u").LeftJoin("user_detail", "ud", "ud.id=u.id").Where("u.id", 1).One()
结合dao
使用示例
// SELECT resource_task_schedule.id,...,time_window.time_window // FROM `resource_task_schedule` // LEFT JOIN `time_window` ON (`resource_task_schedule`.`resource_id`=`time_window`.`resource_id`) // WHERE (time_window.`status`="valid") AND (`time_window`.`start_time` <= 3600) var ( orm = dao.ResourceTaskSchedule.Ctx(ctx) tsTable = dao.ResourceTaskSchedule.Table() tsCls = dao.ResourceTaskSchedule.Columns() twTable = dao.TimeWindow.Table() twCls = dao.TimeWindow.Columns() scheduleItems []scheduleItem ) orm = orm.FieldsPrefix(tsTable, tsCls) orm = orm.FieldsPrefix(twTable, twCls.TimeWindow) orm = orm.LeftJoinOnField(twTable, twCls.ResourceId) orm = orm.WherePrefix(twTable, twCls.Status, "valid") orm = orm.WherePrefixLTE(twTable, twCls.StartTime, 3600) err = orm.Scan(&scheduleItems)
// SELECT DISTINCT resource_info.* FROM `resource_info` // LEFT JOIN `resource_network` ON (`resource_info`.`resource_id`=`resource_network`.`resource_id`) // WHERE (`resource_info`.`resource_id` like '%10.0.1.3%') // or (`resource_info`.`resource_name` like '%10.0.1.3%') // or (`resource_network`.`vip`like '%10.0.1.3%') // ORDER BY `id` Desc LIMIT 0,2 var ( orm = dao.ResourceInfo.Ctx(ctx).OmitEmpty() rTable = dao.ResourceInfo.Table() rCls = dao.ResourceInfo.Columns() nTable = dao.ResourceNetwork.Table() nCls = dao.ResourceNetwork.Columns() ) orm = orm.LeftJoinOnField(nTable, rCls.ResourceId) orm = orm.WherePrefix(rTable, do.ResourceInfo{ AppId: req.AppIds, ResourceId: req.ResourceIds, Region: req.Regions, Zone: req.Zones, ResourceName: req.ResourceNames, Status: req.Statuses, BusinessType: req.Products, Engine: req.Engines, Version: req.Versions, }) orm = orm.WherePrefix(nTable, do.ResourceNetwork{ Vip: req.Vips, VpcId: req.VpcIds, SubnetId: req.SubnetIds, }) // Fuzzy like querying. if req.Key != "" { var ( keyLike = "%" + req.Key + "%" ) whereFormat := fmt.Sprintf( "(`%s`.`%s` like ?) or (`%s`.`%s` like ?) or (`%s`.`%s`like ?) ", rTable, rCls.ResourceId, rTable, rCls.ResourceName, nTable, nCls.Vip, ) orm = orm.Where(whereFormat, keyLike, keyLike, keyLike) } // Resource items. err = orm.Distinct().FieldsPrefix(rTable, "*").Order(req.Order, req.OrderDirection).Limit(req.Offset, req.Limit).Scan(&res.Items)
Content Menu
- No labels
8 Comments
皛心
文档这里写db.Model,我找半天db是啥,折腾半天!!!最后发现这个db.Model就是g.Model。在GoFrame里面g是全局变量,任何应用里都可以直接用。db并没有定义为全局变量。
建议将文档下面的内容更改一下:
海亮
好,我们找个时间优化一下文档中的描述。
jim
Ray
dao写法 如果 on 条件的 字段名不一样怎么写呢
海亮 郭强
大米
dao写法 如果 on 条件的 字段名不一样怎么写呢
同问,LeftJoinOnField 方法为什么只考虑相同的字段,业务中user_id=id这种不是很经常吗
郭强
linquan321
以上查询结果是正常的,有正常的返回值,但是控制台会出现报错,不知道是否bug,还请大佬看看
郭强
linquan321
上面问题版本是v2.3.1,刚发布了v2.3.2测试已无问题,感谢大佬更新。
杨佳佳
scheduleItems这个结构体能出一个示例吗?我想返回2个关联表的所有数据,并重命名left join右面表的ID