oracle老师请进

来源:百度知道 编辑:UC知道 时间:2024/06/14 09:01:06
目前建了一个表test,里面有2个字段id,name
数据如下:
ID, NAME
-- ------
1 A
2 B
3 C
3 C
4 D
2 B
-- -----
通过以下语句找出重复数据
>SELECT * FROM test WHERE ROWID!=(SELECT MAX(ROWID) FROM test tt
WHERE test.id=tt.id AND test.name=tt.name);

结果如下:
ID NAME
--- ----
2 B
3 C

现在我一直看不明白上面查找重复数据的SQL语句,请老师帮我分析一下这个语句在系统中是如何完成的,里面的子查询怎么和外查询协作完成。
请详细指点。
如果明白了,我会加分。谢谢老师。

这个查询是内外相连的,内部的子查询将使用外部表的两个字段。它的执行有点像我们C语言中的循环嵌套,首先它会从外部表test的第一行记录开始取值,带着这一行值进入内部表tt和所有的记录比较一遍。
首先要明白,rowid是逐渐增大的,因此要理解这里的max(rowid)是指符合条件的记录中最后一条记录的行号。
现在看一下执行过程(假设行号分别为1~6):
1 从test表中取出第一条记录即 1 A,带着这行值去和tt中的第一行1 A比较,正好匹配,拿出它的rowid--1,然后再和tt的第二行2 B比较,不匹配,依次取tt的第三行、第四行……,均不匹配,那么子查询的结果max(rowid)就是1,而test表中的1A行号也是1,不满足rowid!=max(rowid)的条件,所以第一行记录1 A 不会被查询出来。
2 从test表中取出第二条记录2 B ,进入内部子查询,在tt中与其匹配的有两条记录分别是第二条和第六条记录,其中最大的行号是第六条记录的行号--6那么test中的2B现在用的是第二条,行号为2,因为2!=6,因此test中的第二行记录2B就被查询出来了。
3 依次看第三条记录3C,与之匹配的是第三条记录和第四条,其中最大行号为 4,因为3!=4,所以3C也会显示。
4 但是需要注意的是第四条记录3C就不会显示了,因为它的行号就是4,进入子查询中与之满足的也是34条记录,最大行号也为4,4!=4,不成立,所以不会讲test表中的第四条记录3C再次显示一遍。
依次处理56条记录,同理……