項(xiàng)目中經(jīng)常會(huì)遇到對(duì)數(shù)據(jù)進(jìn)行分組排序并取前N條的需求门怪,比如有一張資訊表如下
CREATE TABLE `test_news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) DEFAULT NULL COMMENT '文章標(biāo)題',
`content` longtext COMMENT '文章內(nèi)容',
`channel` int(11) DEFAULT NULL COMMENT '文章頻道',
`status` int(11) DEFAULT NULL COMMENT '狀態(tài),1正常罚勾,0關(guān)閉',
`create_time` datetime DEFAULT NULL COMMENT '文章發(fā)布時(shí)間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=513 DEFAULT CHARSET=utf8;
文章分為多個(gè)頻道,比如體育新聞吭狡、娛樂(lè)新聞尖殃、財(cái)經(jīng)新聞、汽車(chē)新聞等多個(gè)頻道划煮,現(xiàn)在要求取出每種類(lèi)型的最新的前5條新聞送丰,避免多次進(jìn)行數(shù)據(jù)庫(kù)連接我們肯定不能每種類(lèi)型都單獨(dú)去請(qǐng)求數(shù)據(jù)庫(kù)查詢,假如種類(lèi)不多的話我們可以分別查出每種新聞的前5條然后使用union all進(jìn)行合并弛秋,這樣也只需要進(jìn)行一次數(shù)據(jù)庫(kù)連接器躏,除了這種方法還有以下兩種方法。
方法一:
由于設(shè)置了表的id自增蟹略,所以最新的資訊可以根據(jù)id來(lái)倒序查也可根據(jù)創(chuàng)建時(shí)間create_time來(lái)進(jìn)行倒序登失,這里采用的id,要取5條最新資訊挖炬,所以查詢的count需要小于5
思路:遍歷所有資訊與當(dāng)前資訊做比較揽浙,同一頻道且相同狀態(tài)的資訊不超過(guò)5個(gè)當(dāng)前的id大,那么這條資訊才算最新的前5條
SELECT
id,
title,
channel,
create_time
FROM
test_news AS a
WHERE
(
SELECT
count(1)
FROM
test_news AS b
WHERE
a.channel = b.channel
AND a. STATUS = b. STATUS
AND a.id < b.id
) < 5
ORDER BY
a.channel ASC,
a.id DESC;
方法二:
SELECT
a.id,
a.title,
a.channel,
a.create_time
FROM
test_news AS a
LEFT JOIN test_news AS b ON a.channel = b.channel
AND a. STATUS = b. STATUS
AND a.id < b.id
WHERE
a. STATUS = 1
GROUP BY
a.channel,
a.id
HAVING
count(1) < 5
ORDER BY
a.channel ASC,
a.id DESC;
方法一查詢結(jié)果
方法二查詢結(jié)果
原文作者技術(shù)博客:http://www.reibang.com/u/ac4daaeecdfe