复杂sql,请大神解析,没办法理解以下这条sql语句。

sql在以下网址第六题:
http://www.cnblogs.com/netserver/p/4518995.html
(里面有建表语句)

select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val ;

想了半天,我始终无法理解这条语句是怎么做到筛选出最大的2条val值的,并且如果做到了分组了的呢?都没见到有group by这条语句。这条嵌套查询究竟做了什么?有大神能详细解释下吗,感谢。一有这种和查询的表直接嵌套的我都有点懵 ,目前还没用过。。。常用的都是外连接,内连接,自连接,多表连接这些都能理解。因为理解这些只需要搞清楚执行顺序,还有一些基础知识就差不多了。像上面这种真的不知道在干啥啊?

可以想象成表tb互相join查找, 嵌套查询是找name相同时候,比val值大的记录数目,如果记录数小于2,那说明这条记录就是最大的两条之一了。
最后是按名字,val排序输出。

具体分析一下:
第一条记录为 a 2 a2(a的第二个值)
嵌套查询是从tb表中找name=a 并且val>2的记录,数个数(count*) 一共是0条,小于2,所以第一条记录满足条件,是最大的2条记录之一。
依次执行
到第五条记录 b 3 b3:b的第三个值
从tb表找name=b,并且val>3的记录,一共是2条,那么2不小于2,所以这一条不满足。

最后按name,val排序得到结果。

不知道这样解释你能不能理解。

当执行一条 select 语句的时候,MySQL会遍历每一条数据(像 for 循环似的),一条一条比较它是否符合后面的条件,符合的就留下,不符合的就略过。

当每一条数据被读到的时候,小括号中 a.name 和 a.val 得到的就是当前这条数据的值。

所以说,小括号中的 name=a.name,就是筛选出与本条数据的 name 相同的所有数据。在所有 name 相同的数据中 val 比我大的有0个,那我就是最大的;val比我大的有1个,那我就是第二大的。

也就是说,小括号得到的其实是针对每条数据的一个计算值:和我name相同的数据中,比我val值大的数量有几个。

有0个,那我就是最大的;有一个,那我就是第二大的。这样,就把第一第二大的值挑出来了。

分组的话其实是这一句就做到了分组的效果:where name = a.name
整个语句其实将表里的每一条数据都比较了一次,不过是在比较时候将不是同名的数据都过滤掉了,只与同名的做比较这里就相当于是group by name了,
然后是查找出符合条件的也就是在同名的数据中,没有超过两条记录的val比自己大的。
这种写法很有意思,值得学习!!!