复杂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这条语句。这条嵌套查询究竟做了什么?有大神能详细解释下吗,感谢。一有这种和查询的表直接嵌套的我都有点懵 ,目前还没用过。。。常用的都是外连接,内连接,自连接,多表连接这些都能理解。因为理解这些只需要搞清楚执行顺序,还有一些基础知识就差不多了。像上面这种真的不知道在干啥啊?

3个回答

可以想象成表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排序得到结果。

weixin_44046998
weixin_44046998 分组怎么解释呢?一般的外连接,内连接分组,除了需要连接条件外,还需要使用group by语法。这种就直接分组了吗
7 个月之前 回复

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

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

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

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

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

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

weixin_44046998
weixin_44046998 大神阿,看来sql还有很多我不知道的。有没有什么好的书推荐阿。还是说一切慢慢去领悟。
7 个月之前 回复
lnotime
Inotime 回复weixin_44046998: 假设SQL执行判断到第8条数据,此时小括号中的a.name的值是b,小括号中a.val的值是5,小括号中的执行就是select count(*) from tb where name = 'b' and val > 5,小括号中得到的结果是0,然后2>0,所以第八条数据被保留下来了。
7 个月之前 回复
lnotime
Inotime 回复weixin_44046998: 他没分组,只是结果和分组类似而已。
7 个月之前 回复
weixin_44046998
weixin_44046998 嗯,明白了,那为什么会默认进行分组呢?a.name=name这不过是一个连接条件呀,它是怎么做到了分组的。
7 个月之前 回复

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

qq_36720114
德玛洗牙 回复weixin_44046998: 就我个人理解而言,我觉得用group by进行分组更多的是用于按分组统计,而这里是要取出整条数据就需要对所有列进行groupby,但这在没有重复数据的情况下写与不写结果都一样
7 个月之前 回复
weixin_44046998
weixin_44046998 为啥这样能进行分组,刚才我也想到了。但是没有任何说明阿,普通的外连接,内连接等用where条件进行分组都需要group by。像这种嵌套表的为啥能这样做。
7 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!