日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Laravel Query Builder 复杂查询案例:子查询实现分区查询 partition by

發(fā)布時(shí)間:2025/3/17 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Laravel Query Builder 复杂查询案例:子查询实现分区查询 partition by 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

案例

案例:[Laravel 在文章列表中附帶上前10條評(píng)論?][1],在獲取文章列表時(shí)同時(shí)把每個(gè)文章的前10條評(píng)論一同查詢出來(lái)。

這是典型分區(qū)查詢案例,需要根據(jù) comments 表中的 post_id 字段進(jìn)行分區(qū),同時(shí)根據(jù)條件進(jìn)行排序,把符合條件的前 N 條是數(shù)據(jù)取出來(lái)。

在其他數(shù)據(jù)庫(kù)(Oracle, SQL Server,Vertica) 包含了 row_number partition by 這樣的函數(shù),能夠比較容易的實(shí)現(xiàn)。

比如在 SQL Server 中:

SELECT * FROM ( SELECT *, row_number() OVER (partition by post_id ORDER BY created_at desc) rank FROM comments where post_id in (1,2,3,4,5) ) b where rand < 11; 復(fù)制代碼

在 mysql 中要復(fù)雜一些,我們先來(lái)看看上面案例中實(shí)現(xiàn)需求的幾種解決辦法。

解決辦法

方法1:

在 blade 中要顯示評(píng)論數(shù)據(jù)的地方 post->comments()->limit(10)

問(wèn)題:如果取了 20 條 Post 數(shù)據(jù),就會(huì)有 20 條取 comments 的 sql 語(yǔ)句,會(huì)造成執(zhí)行的 sql 語(yǔ)句過(guò)多。

不是非常可取,主要問(wèn)題會(huì)造成 SQL 語(yǔ)句過(guò)多,對(duì)數(shù)據(jù)庫(kù)服務(wù)器產(chǎn)生壓力,不過(guò)這里可以使用緩存來(lái)改進(jìn),但是不在本文章討論范圍里。

方法2:

直接通過(guò) with 把 Post 的所有 comments 數(shù)據(jù)都取出來(lái),在 blade 中 post->comments->take(10)

問(wèn)題:Laravel 會(huì)預(yù)先把文章所有的評(píng)論數(shù)據(jù)查詢出來(lái),如果文章的評(píng)論數(shù)據(jù)非常多,可能會(huì)造成內(nèi)存泄漏。

方法3:

$posts = Post::paginate(15);$postIds = $posts->pluck('id')->all();//找出符合條件的 comments ,同時(shí)定義 @post, @rank 變量,這里沒(méi)有用 all,get 等函數(shù),此時(shí)并不會(huì)執(zhí)行 SQL 語(yǔ)句。 $sub = Comment::whereIn('post_id',$postIds)->select(DB::raw('*,@post := NULL ,@rank := 0'))->orderBy('post_id');//把上面構(gòu)造的 sql 查詢作為子表進(jìn)行查詢,根據(jù) post_id 進(jìn)行分區(qū)的同時(shí) @rank 變量不斷+1 $sub2 = DB::table( DB::raw("({$sub->toSql()}) as b") )->mergeBindings($sub->getQuery())->select(DB::raw('b.*,IF (@post = b.post_id ,@rank :=@rank + 1 ,@rank := 1) AS rank,@post := b.post_id'));//取出符合條件的前10條comment $commentIds = DB::table( DB::raw("({$sub2->toSql()}) as c") )->mergeBindings($sub2)->where('rank','<',11)->select('c.id')->pluck('id')->toArray();$comments = Comment::whereIn('id',$commentIds)->get();$posts = $posts->each(function ($item, $key) use ($comments) {$item->comments = $comments->where('post_id',$item->id); }); 復(fù)制代碼

會(huì)產(chǎn)生三條sql

select * from `posts` limit 15 offset 0;select `c`.`id` from (select b.*,IF ( @post = b.post_id ,@rank :=@rank + 1 ,@rank := 1 ) AS rank, @post := b.post_id from (select *,@post := NULL ,@rank := 0 from `comments` where `post_id` in ('2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16') order by `post_id` asc) as b) as c where `rank` < '11';select * from `comments` where `id` in ('180', '589', '590', '3736'); 復(fù)制代碼

知識(shí)點(diǎn)

  • toSql() 方法的作用是為了獲取不帶有 binding 參數(shù)的 SQL, 也就是說(shuō)帶問(wèn)號(hào)的 SQL
  • getQuery() 方法的作用是為了獲取 binding參數(shù)并代替 toSql() 獲得SQL的問(wèn)號(hào),從而得到完整的SQL
  • raw() 的作用是直接把 SQL 套進(jìn) Laravel 的查詢構(gòu)造器中。
  • mysql 查詢語(yǔ)句中定義變量 @post := NULL ,@rank := 0 以及 IF 函數(shù)的使用
  • 如何構(gòu)建子查詢。
  • 為什么不直接用原生 SQL 語(yǔ)句來(lái)實(shí)現(xiàn)?

    這里之所以堅(jiān)持使用 Laravel Query Builder 來(lái)實(shí)現(xiàn),可以有效防止 SQL 注入,并且和 ORM 的 Model 對(duì)象關(guān)聯(lián)起來(lái)。

    如果還有更多類似這種復(fù)雜的需求,歡迎聯(lián)系我 : )

    討論交流

    總結(jié)

    以上是生活随笔為你收集整理的Laravel Query Builder 复杂查询案例:子查询实现分区查询 partition by的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 激情国产视频 | 成人av视屏 | 国产aⅴ爽av久久久久成人 | 夜夜嗨aⅴ一区二区三区 | 影音先锋蜜桃 | 国产专区在线 | 欧美激情视频一区 | 日本在线视频一区二区三区 | 北条麻妃一区二区三区四区五区 | 人妻精品久久久久中文字幕69 | 黄色片特级 | 欧美日韩精品一区二区三区 | 一级美女大片 | 亚洲免费视频一区二区三区 | 综合色婷婷一区二区亚洲欧美国产 | 黄色一级片免费 | 久久亚洲精 | 中文字幕视频在线 | 国产无毛片 | 中文字幕素人 | 粗大挺进潘金莲身体在线播放 | 人妻一区二区三区免费 | 人人澡人人看 | 国产毛片91| 爱爱免费视频 | 欧美日韩亚洲激情 | 国产高清在线不卡 | 久久99国产综合精品免费 | 亚洲午夜视频 | 一区二区日韩在线观看 | 扒下小娇妻的内裤打屁股 | 夜夜躁狠狠躁日日躁 | 精品一区二区三区免费毛片 | 久久人人爽人人爽人人片av免费 | 日批视频免费在线观看 | 蜜桃视频无码区在线观看 | 精品一卡二卡三卡 | 精品国产18久久久久久 | 中国黄色三级视频 | 精品国产99 | 成人免费av | 操久久久| 国产福利在线视频观看 | 污视频网站在线看 | 欧美人与动物xxx | 亚洲最新av | 国产天堂| 污污视频在线观看免费 | 黄色国产毛片 | 一级黄色大全 | 又黄又高潮的视频 | 欧美20p| 天天射天天干天天舔 | 国产精品亚洲αv天堂无码 伊人性视频 | 精品国产综合 | 欧美久久99 | 日韩a√| 国产深喉视频一区二区 | 女人高潮被爽到呻吟在线观看 | 天天夜夜草 | 电影一区二区三区 | 精品视频一区二区三区四区 | 欧美中文视频 | 成人国产精品久久久网站 | 免费大片在线观看www | 欧美日韩国产三级 | 婷婷tv| 国产av天堂无码一区二区三区 | 欧美系列在线观看 | 99久久精品无免国产免费 | 三日本三级少妇三级99 | 日本在线观看免费 | 国内偷拍精品视频 | 少妇精品无码一区二区 | 国产中文在线播放 | 麻豆传媒在线观看 | 欧美一区二区三区在线视频 | 成人av在线网址 | 午夜一区二区三区在线 | 69福利网| 曰本丰满熟妇xxxx性 | 放荡闺蜜高h季红豆h | 国产一级久久久久毛片精品 | 成年人视频网 | 午夜电影一区二区三区 | 欧美一区二区在线免费观看 | 韩国jizz| 这里有精品视频 | 亚洲国产精品久久久久久久 | 日韩毛片一区 | 在线视频观看一区 | www欧美com| 亚洲国产一区二区在线观看 | 国产成a人亚洲精v品在线观看 | 久草视频首页 | 邻居校草天天肉我h1v1 | 美国av大片 | 午夜精品久久久久久久99 | 久久国产视频网 |