ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 逻辑有点难理解的Sql执行结果,以及用处

逻辑有点难理解的Sql执行结果,以及用处

原创 Linux操作系统 作者:ljm0211 时间:2012-06-20 13:42:20 0 删除 编辑
准备测试环境:
create table kevintest (col1 char(1),col2 char(2),col3 int);
insert into kevintest values('A','B',2);
insert into kevintest values('A','B',3);
insert into kevintest values('A','B',4);
insert into kevintest values('A','C',1);
insert into kevintest values('A','C',2);
insert into kevintest values('A','C',3);
insert into kevintest values('A','C',4);
insert into kevintest values('A','C',5);


分析对象:
SELECT *
FROM kevintest c
WHERE col1 = 'A' AND col3 = (SELECT MAX (col3)
                                FROM kevintest
                               WHERE col1 = c.col1 AND col2 = c.col2)
执行结果:


理解执行逻辑,先从kevintest c Table中以条件col1='A'取得记录集,针对记录集中每条记录(例如记录“AB3”),使用条件col3=(……),同时每条记录中“AB”的值又作为了子查询中的条件,通过子查询取得结果后再对记录“AB3”进行过滤,在本例中“AB”传入子查询取得结果为“4”,对"AB3"进行过滤会将"AB3这条记录过滤掉,因为这条记录不满足col3=4(子查询结果)。
依次分析记录,发现"AB4"会被留下作为查询结果的一条记录。“AC5”会被留下作为查询结果的一条记录。
通过结果我们可以看出,在子查询中传入相同表的col1和col2进行连接并对结果使用集合函数时,实际SQL取得的结果相当于在表kevintest中对col1和col2做group by的操作,取得每个结果组中col3最大(或其他聚合函数)的记录。
这个group by col1,col2操作从Sql Server显示的执行计划中也可以看到。SQL:select col1,col2,max(col3) from kevintest group by col1,col2,能得到与分析对象相同的结果。不过在某些情况下这句SQL还无法代替分析对象的写法。因为我们知道在使用聚合函数时,select后面不能接group by和聚合函数操作的对象之外的列。如果试验Table中在有col4,select col1,col2,col4,max(col3) from kevintest group by col1,col2,这样写法就会报错。而分析对象就可以避免这个问题。
结论:
分析对象:
SELECT *
FROM kevintest c
WHERE col1 = 'A' AND col3 = (SELECT MAX (col3)
                                FROM kevintest
                               WHERE col1 = c.col1 AND col2 = c.col2)
在Table kevintest中取得以col1和col2分组的各组中col3最大的记录,所得记录数等于以col1和col2分组所得到的组的个数。

PS:实现与分析对象相同功能还有一个写法,这种写法看起来好理解一些,不过Sql Server的写法看起来没有分析对象简洁,还要考虑各个列的类型转换。不过Oracle的写法不用考虑类型转换的问题,不过Oracle的问题在与这种写法在Sql Server里是有语法错误的。
Sql Server写法:
SELECT *
FROM kevintest c
WHERE col1 = 'A' AND col1+'|'+col2+'|'+CHAR(col3) in (SELECT col1+'|'+col2+'|'+CHAR(MAX (col3))
                                FROM kevintest group by col1,col2)
Oracle写法:
SELECT *
FROM kevintest c
WHERE col1 = 'A' AND (col1,col2,col3) in (SELECT col1,col2,MAX (col3)
                                FROM kevintest group by col1,col2)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/11411056/viewspace-733359/,如需转载,请注明出处,否则将追究法律责任。

下一篇: DUMP函数
请登录后发表评论 登录
全部评论

注册时间:2009-05-14

  • 博文量
    272
  • 访问量
    437122