返回信息流有一个表STU:
SNO | ID
1 | 1
1 | 2
2 | 3
2 | 4
3 | 5
要查询其中的重复项:
[已更正的写法]
SELECT * FROM STU A WHERE ( SNO IN (SELECT SNO FROM STU B WHERE A.ID<> B.ID))
返回:
SNO | ID
1 | 1
1 | 2
2 | 3
2 | 4
可我不明白这句SQL语句是怎么执行的,特别是A.ID<> B.ID,这句不明白。请教其详细的运行过程?先执行哪一句,得到什么结果?
这是一条镜像帖。来源:北邮人论坛 / database / #5982同步于 2011/9/25
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Database机器人发帖
菜鸟问题,帮看一行SQL语句是怎么执行的?
wqchen
2011/9/25镜像同步7 回复
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
【 在 wqchen 的大作中提到: 】
: 有一个表STU:
: SNO | ID
: 1 | 1
: ...................
首先是这个看不懂,就算把Id改成SNO也看不懂,其次你这个根本查不出数据,好人做到底,我给你写一个吧。
select * from stu where Id not in
(select Id from stu group by SNO having count(*)< 2);
抱歉!
写错了,更正如下:
SELECT * FROM STU A WHERE ( SNO IN (SELECT SNO FROM STU B WHERE A.ID<> B.ID))
目的是查SNO有重复的记录,而ID是不会重复的,上述语句是我从网上看到的,不理解A.ID<> B.ID是怎么工作的。
LS的写法是可以达到同样的目的,不过我还是想理解一下网上的这种写法?
【 在 wangjianzhou 的大作中提到: 】
: : 有一个表STU:
: : SNO | ID
: : 1 | 1
: ...................
高手写出来的,请教一下技术群,才算弄懂,确实很费人。
大概说一下我看懂的,A表的SNO和B表SNO一样,但是主键Id不一样。
扫描第一行时候,就是A的ID是1时候,A的sno等于1,这是B表的SNO也要等于1,但是主键不能等于1,所以B表取出的是第二行。
下一步,A表扫第二行的时候,B表是第一行。
依次循环。
【 在 wangjianzhou 的大作中提到: 】
: 高手写出来的,请教一下技术群,才算弄懂,确实很费人。
: 大概说一下我看懂的,A表的SNO和B表SNO一样,但是主键Id不一样。
: 扫描第一行时候,就是A的ID是1时候,A的sno等于1,这是B表的SNO也要等于1,但是主键不能等于1,所以B表取出的是第二行。
: ...................
按LS上说的的思路去跟踪了下,倒是可以明白选择出来的行了,但仔细对照选择出来的顺序,感觉理解还是困难:
原表:
SNO | ID
1 | 1
1 | 2
1 | 3
2 | 4
2 | 5
3 | 6
选择出来的记录,注意看ID的顺序是倒序的(不理解这里):
SNO | ID
1 | 3
1 | 2
1 | 1
2 | 5
2 | 4
按LS上启发,我是这样理解的:A先选择,选出第一行,B也选出第一行,不行,B继续选第二行,好的可以,于是输出A的第一行,但这应该就是(1,1)了吧?
这里面是不是还有个问题:是第一个SELECT还是第二个SELECT先执行呢?
相关子查询的执行依赖于外部查询。多数情况下是子查询的WHERE子句中引用了外部查询的表。执行过程:
(1)从外层查询中取出一个元组,将元组相关列的值传给内层查询。
(2)执行内层查询,得到子查询操作的值。
(3)外查询根据子查询返回的结果或结果集得到满足条件的行。
(4)然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕。
【 在 wqchen (生猛海鲜) 的大作中提到: 】
: 按LS上说的的思路去跟踪了下,倒是可以明白选择出来的行了,但仔细对照选择出来的顺序,感觉理解还是困难:
: 原表:
: SNO | ID
: ...................
For certain cases, a correlated subquery is optimized. For example:
val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)
Otherwise, they are inefficient and likely to be slow. Rewriting the query as a join might improve performance.
http://dev.mysql.com/doc/refman/5.5/en/correlated-subqueries.html
如果保证子查询没有重复 ,IN、EXISTS的相关子查询可以用INNER JOIN 代替。
SQL 查询: SELECT a.sno, a.id FROM `stu` b INNER JOIN stu a ON a.sno = b.sno AND a.id <> b.id LIMIT 0, 30 ;
行数: 8
sno id
1 1
1 1
1 2
1 2
1 3
1 3
2 4
2 5
SQL 查询: SELECT distinct a.sno, a.id FROM `stu` b INNER JOIN stu a ON a.sno = b.sno AND a.id <> b.id LIMIT 0, 30 ;
行数: 5
sno id
1 1
1 2
1 3
2 4
2 5
至于结果的行序,理论上如果你没排序的话,是没有意义的
【 在 wqchen (生猛海鲜) 的大作中提到: 】
: 有一个表STU:
: SNO | ID
: 1 | 1
: ...................