MySQL查询分组后前10条数据

在做去哪儿网数据分析时候被一个问题难倒了,之前通过scrapy将数据导入了MySQL,然后想分组查询MySQL数据库每个省份每个分组300条数据,但结果。。。

由此,机智的我打开了Google和百度,在广大网友的支持下,姑且找到了解决问题的办法。但有个问题还是没有解决,查询后返回结果数目不等。最后结果是这样的
运行结果

不明白结果怎么来的,头疼,等我成长为菜鸟+的时候估摸着就明白了,现在还是菜鸟-的状态。

相关子查询我会啊

SELECT m1.city,m1.title
FROM message m1
LEFT JOIN message m2
ON m1.`city`=m2.`city`
GROUP BY m1.`city`
ORDER BY m1.`city`;

结果返回了32条数据


返回数据

羊毛出在了羊身上,原因在于用group by查询数据时,会将数据分组合并,然后数据就成了32条了,也就是32个省市自治区(台湾也有)。
然后我又来了一次

SELECT city,title
FROM (SELECT *
FROM message
ORDER BY city) m;
返回结果

貌似成功了,但从哪儿分组呢,分组体现在哪儿呢,加不进去啊???

于是乎,求助万能的百度,得到了如下结果:

第一个就是相关子查询了

关联子查询会引用外部查询中的一列或多列。这种子查询之所以被称为关联子查询,是因为子查询的确与外部查询有关。当问题的答案需要依赖于外部查询中包含的每一行中的值时,通常就需要使用关联子查询。

然后得到了如下结果

  • 非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询,并且它是优先于外部查询先执行的,他执行了再执行外部。
  • 相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。并且是外部先查询一次,然后再执行一次内部查询!

执行过程如下

  • 从外层数据中取出一条数据,传递给内层数据查询
  • 内层查询操作得到相应的值
  • 外查询根据内查询的相关结果或结果集得到相应的行(满足一定条件)
  • 然后重复操作,直到完成任务

然后大致懂得了操作

SELECT m1.city,m1.title
FROM message m1
WHERE 10>(
    SELECT COUNT(1)
    FROM message m2
    WHERE m1.`id`>m2.`id` AND m1.`city`=m2.`city`
    )
ORDER BY m1.city,m1.title;
正确结果

这个结果我猜想是这么运行的:
首先了解MySQL语句执行顺序,这个至关重要

Where -> Group By -> Having -> Order by

这条语句中,父查询传入语句到子查询中,count语句查询出当前子查询语句中查询到的行,如果父查询的所有数值(id)都比他大,那这条语句(行)处于第一位,返回结果为1。同理,进行多次查询,得到另一个条件(city)相同前提下中每个元素所处位置。事情这样就简单了,父查询select一下再加入筛选条件即可得到正确结果。
另外,这个语句还可以通过连接方式查询

SELECT m1.city,m1.title
FROM message m1
LEFT JOIN message m2
ON m1.`id` >m2.`id`AND m1.`city`=m2.`city`
GROUP BY m2.`city`,m2.id
HAVING COUNT(*)<=10
ORDER BY m1.city;

这样跑起来也是正确的


正确结果

内连接也是可以的

SELECT m1.city,m1.title
FROM message m1
INNER JOIN message m2
ON m1.`id` >= m2.`id`AND m1.`city`=m2.`city`
GROUP BY m2.`city`,m2.id
HAVING COUNT(*)<=10
ORDER BY m1.city;
正确结果

有一点需要注意的是,三者运行时间有所差异,第一种方法运行速度比较快,连接方式查询明显慢一点。

最后,复习了一下基础查询方法

分类

  1. 按照子查询出现的位置
  • select后面
    仅仅支持标量子查询
  • from后面
    仅仅支持表子查询
  • where或having后面
    标量子查询
    列子查询
    行子查询
  • exists后面(相关子查询)
    表子查询

按照结果集的行列数不同

  • 标量子查询(结果集只有一行一列)
  • 列子查询(结果集只有一列多行)
  • 行子查询(结果集有一行多列)
  • 表子查询(结果集一般为多行多列)

你可能感兴趣的:(MySQL查询分组后前10条数据)