这是表的结构
首先尝试自己写,但是所有东西都还给老师了。一时间风中凌乱,没有丝毫头绪,怎么拆分子查询等都忘光光。
#1.查询某个类型阅读量前10的数据
SELECT
ArticleId,
UserId,
Title,
CreateTime,
TypeId,
PageView
FROM
article
WHERE TypeId = 2
ORDER BY
PageView DESC
LIMIT 10
2.#查询每个类型文章中前10条数据
SELECT
ArticleId,
UserId,
Title,
CreateTime,
TypeId,
PageView
FROM
article a
WHERE
10 > (
SELECT
COUNT(*)
FROM
article
WHERE
TypeId = a.Typeid
AND ArticleId > a.ArticleId
)
最终只写到这一步 。仔细想想,在这些的基础上只要再琢磨琢磨就能得到答案!
可是,越想越乱,越乱越想……
然后开始百度ing……
最后发现,在查询的时候需要计算出每个类型的文章存在的行数,然后要查询多少条随意。然后又是百度修改来的代码
SELECT
a3.ArticleId,
a3.UserId,
a3.Title,
a3.CreateTime,
a3.TypeId,
a3.PageView
FROM
(
SELECT
a1.*,
(
SELECT
COUNT(*)
FROM
article a2
WHERE
a1.PageView <= a2.PageView
AND a1.TypeId = a2.TypeId
) AS rownum
FROM
article a1
) a3
WHERE
rownum <=10
ORDER BY
TypeId,
PageView DESC;
查询方式多种多样,参考大佬的博客
mysql分组取每组前几条记录(排名) 附group by与order by的研究
但是!但是!
无论按照哪种方法,查询出来的结果,要么不是少了几条,要么就是把所有数据都分组后查询出来,没有达到要求的结果
最后,还是百度
最终思路:从表中按照分类和阅读量按照降序进行分组,记录下每次分组的行数,然后将分组后的查询到的数据返回给父查询,然后父查询中就可以控制查询需要的行。
SELECT
a.ArticleId,
a.UserId,
a.Title,
a.CreateTime,
a.TypeId,
a.PageView
FROM
(
SELECT
a1.*, @rn := CASE
WHEN @var_TypeId = TypeId THEN
@rn + 1
ELSE
1
END AS rn,
@var_TypeId := TypeId
FROM
article a1,
(
SELECT
@rn := 0 ,@var_TypeId := 0
) AS vars
WHERE
TypeId IN (SELECT TypeId FROM article)
ORDER BY
TypeId,
PageView DESC
) AS a
WHERE
rn <= 10
ORDER BY
TypeId,
PageView DESC
SQL的语句的思想与前面的近乎相同,不同的是利用了case then这个一般在存储过程用的鬼东西来帮助记录下每个类型的中数据的条数,然后最外层只要规定这个变量rn 就是你要查询的条数。
这个方法能够正确的查询出要的数据
参考大佬的文章 查询数据分组之后的前几条数据 可根据不同情况筛选