鍍金池/ 問(wèn)答/PHP/ laravel下 如何更優(yōu)雅的實(shí)現(xiàn)這個(gè)數(shù)據(jù)查詢需求

laravel下 如何更優(yōu)雅的實(shí)現(xiàn)這個(gè)數(shù)據(jù)查詢需求

背景

laravel 版本

5.4

數(shù)據(jù)表關(guān)系

res 資源
tag 標(biāo)簽

資源 和 標(biāo)簽是多對(duì)多關(guān)系,所以有中間表 res_tag。

問(wèn)題

我希望取出一個(gè)資源列表,要求如下:

  • 最新的5條
  • tag.id in (1,3,5)

笨方法

我用查詢構(gòu)造器,實(shí)現(xiàn)這樣的SQL語(yǔ)句。

SELECT
    *
FROM
    res
LEFT JOIN res_tag ON res_tag.res_id = res.id
WHERE
    res_tag.tag_id IN (1, 3, 5)

期望答案

laravel 中是否有更優(yōu)雅的實(shí)現(xiàn)方法。

我對(duì)更優(yōu)雅的定義:比如利用ORM的 “關(guān)聯(lián)” 是否能實(shí)現(xiàn)?

20171205,追問(wèn)

非常感謝 @nopainnogain 的解答,我做了如下修改。

代碼

knowledge 就是 tag(上文我為了敘述問(wèn)題,做了簡(jiǎn)化)

$knowledge = new Knowledge();
$res = $knowledge->res()
    ->whereIn('knowledge_id', $knowledge_ids)
    ->orderBy('created_at', 'desc')
    ->limit(5)->get();

SQL

實(shí)際執(zhí)行的SQL語(yǔ)句,程序自動(dòng)添加了 knowledge_res.knowledge_id IS NULL 這個(gè)查詢條件,導(dǎo)致查不出任何數(shù)據(jù)。(去掉此查詢條件,結(jié)果能滿足需求

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。

不知道是解答時(shí)手誤還是我其他環(huán)節(jié)出了問(wèn)題。

回答
編輯回答
安若晴

你這是標(biāo)準(zhǔn)的多對(duì)多模型關(guān)聯(lián)
在你的資源Model里定義個(gè)新方法:

public function tags()
{
    return $this->belongsToMany('標(biāo)簽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();
2018年4月27日 03:25