Mysql 中實(shí)現(xiàn)文章置頂分頁

先說一下背景吧:現(xiàn)在有一張表learn_article,里面有一個字段hot,當(dāng)hot值為1時表示文章置頂,現(xiàn)在要分頁查詢文章列表,要求置頂文章放在最前面然后按id倒序排列,其他文章按id倒序排列。
  提到置頂還獲取列表,我當(dāng)然想到使用UNION啦,于是就寫出了下面這個SQL:

SELECT id,hot FROM 
((SELECT * FROM learn_article WHERE hot = 1 ORDER BY id DESC)
UNION 
(SELECT * FROM learn_article WHERE hot!= 1 ORDER BY id DESC))A
LIMIT 1,10
錯誤的置頂分頁 1

然而,從結(jié)果也可以看出它不是我想要的結(jié)果,為毛它沒有執(zhí)行ORDER BY id DESC啊!查閱了UNION相關(guān)說明才知道:
聯(lián)合查詢不僅僅是將數(shù)據(jù)集合合并,他并不是將每個子查詢一個一個查詢出來后聯(lián)接在一起,數(shù)據(jù)庫是將整段查詢語句解釋之后統(tǒng)一查詢得到的是整個的數(shù)據(jù)集合。另外order by在一個數(shù)據(jù)集合查詢里也只能被執(zhí)行一次并且要放在最后一個查詢子句后,所以上面查詢子句中的ORDER BY id DESC會被Mysql忽略!
  因此,在聯(lián)合查詢里,order by 要寫在最后一個子查詢之后,并且,該排序是對整個聯(lián)合查詢出來的結(jié)果集排序的,并不是只對最后一個子查詢排序,像下面這樣:

SELECT id,hot FROM learn_article WHERE hot = 1
UNION 
SELECT id,hot FROM learn_article WHERE hot!= 1 
ORDER BY id DESC  LIMIT 1,10
錯誤的置頂分頁 2

  但是,這更不是我要的結(jié)果啊??!到底還要我怎樣呢!后來查閱資料發(fā)現(xiàn):在使用UNION連接多個查詢結(jié)果的情況下,想要在每個select子句使用ORDER BY 就需要同時使用limit!這樣的話問題好像就能解決啦:

SELECT id,hot FROM (
(SELECT * FROM learn_article WHERE hot = 1 ORDER BY id DESC LIMIT 0,3)
UNION 
(SELECT * FROM learn_article ORDER BY id DESC LIMIT 0,10))A
正確但麻煩的置頂分頁查詢

  但是問題來啦,我怎么知道置頂?shù)奈恼虏閹讞l,非置頂?shù)奈恼虏閹讞l呢?那只有再查詢一下置頂文章的條數(shù)啦:

SELECT COUNT(*) FROM learn_article WHERE hot =1

然后再根據(jù)查詢起點(diǎn)offset和查詢條數(shù)limit,計算置頂文章查詢的數(shù)量(tlimit)和非置頂文章的查詢起點(diǎn)(loffset)和查詢數(shù)量(flimit):

int offset = Integer.valueOf(request.getParameter("offset"));
int limit = Integer.valueOf(request.getParameter("limit"));
//查詢置頂文章數(shù)量,置頂文章不超過一頁
int topNum = this.articleService.countTop(params);
int tlimit = topNum ;
int foffset = offset;
int flimit = limit;

if(topNum < offset){
    //第二頁以后
    offset-=topNum;
    tlimit =0;
}else{
    //第一頁
    flimit = limit - topNum > 0 ? limit - topNum : 0;
    tlimit = topNum;
}

然后就將tlimit,foffset,flimit傳到后臺,進(jìn)行查詢:

SELECT id,hot FROM (
(SELECT * FROM learn_article WHERE hot = 1 ORDER BY id DESC LIMIT 0,#{tlimit})
UNION 
(SELECT * FROM learn_article ORDER BY id DESC LIMIT #{foffset},#{flimit}))A

這樣就是實(shí)現(xiàn)了文章置頂?shù)姆猪摬樵?,是在太麻煩啦,到是有一種操作簡單的方法就是使用FIND_IN_SET:
SELECT * FROM learn_article ORDER BY FIND_IN_SET(hot,'1') DESC ,id DESC LIMIT 0,10;

使用FIND_IN_SET實(shí)現(xiàn)置頂分頁

但是呢,大家都知道的FIND_IN_SET執(zhí)行效率太低啦,而且費(fèi)內(nèi)存!大家要是有更好的辦法一定要告訴我哦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容