为了账号安全,请及时绑定邮箱和手机立即绑定

laravel下 如何更优雅的实现这个数据查询需求

laravel下 如何更优雅的实现这个数据查询需求

PHP
沧海一幻觉 2019-03-17 00:32:11
背景 laravel 版本 5.4 数据表关系 res 资源tag 标签 资源 和 标签是多对多关系,所以有中间表 res_tag。 问题 我希望取出一个资源列表,要求如下: 最新的5条 tag.id in (1,3,5) 笨方法 我用查询构造器,实现这样的SQL语句。 SELECT * FROM res LEFT JOIN res_tag ON res_tag.res_id = res.id WHERE res_tag.tag_id IN (1, 3, 5) 期望答案 laravel 中是否有更优雅的实现方法。 我对更优雅的定义:比如利用ORM的 “关联” 是否能实现? 20171205,追问 非常感谢 @nopainnogain 的解答,我做了如下修改。 代码 knowledge 就是 tag(上文我为了叙述问题,做了简化) $knowledge = new Knowledge(); $res = $knowledge->res() ->whereIn('knowledge_id', $knowledge_ids) ->orderBy('created_at', 'desc') ->limit(5)->get(); SQL 实际执行的SQL语句,程序自动添加了 knowledge_res.knowledge_id IS NULL 这个查询条件,导致查不出任何数据。(去掉此查询条件,结果能满足需求) SELECT * FROM `res` INNER JOIN `knowledge_res` ON `res`.`id` = `knowledge_res`.`res_id` WHERE `knowledge_res`.`knowledge_id` IS NULL AND `knowledge_id` IN ( 164, 165, 166, 167, 168, 169, 170 ) AND `res`.`deleted_at` IS NULL ORDER BY `created_at` DESC LIMIT 5 另外,有一事疑惑 回答中代码:资源Model::query()->tags() 生成的SQL: select * from tag inner 资源 ... 这样取出的资源是以 tag 为主的,我希望是资源列表 所以我改为:tagModel::query()->资源() 生成的SQL:select * from 资源 inner join tag ... 也就是上文提供的SQL。 不知道是解答时手误还是我其他环节出了问题。
查看完整描述

1 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

你这是标准的多对多模型关联
在你的资源Model里定义个新方法:

public function tags()
{
    return $this->belongsToMany('标签Model');
}

然后:

资源Model::query()
->tags()
->whereIn('res_id',[1,3,5])
->orderBy('create_time','desc')
->limit(5)
->get();

2017-12-5
试试:

ResModel::whereHas('knowledge', function ($query) use ($knowledge_ids) {
    $query->whereIn('knowledge_id', $knowledge_ids);
})
->orderBy('created_at', 'desc')
->limit(5)
->get();
查看完整回答
反对 回复 2019-03-18
  • 1 回答
  • 0 关注
  • 436 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信