假设是这样一个SQL文:SELECT * FROM A, B;在SELECT文实现二表连接时,系统首先执行FROM字句,这里FROM字句列出的有A和B两个表,DBMS将计算这两个表的笛卡尔积,列出这两个表中行的所有可能组合。假设A表有5行,B表有7行,那么最终被抽取的数据将会是5*7=35行。到这里为止一切OK,但是当抽取出数据以后发现,根据数据的内容不同,它的排列组合也不同,我一直以为最终结果将是A*B的笛卡尔积,结果发现在某种情况下是B*A的笛卡尔积。我想应该是DBMS在抽取数据时,或者数据后对数据进行了某种操作。我查了一些手上的文档和网上的资源,都没有找到答案(可能是鄙人查找资源能力不强),恳请大家帮忙告知我一个答案,在这里先谢过大家了。以下是我测试的例子,例子很简单,见笑了。
测试环境:ORACLE10g/SQLPLUS1.SELECT TAB1.NO,TAB2.ALPH FROM TAB1, TAB2;
TAB1:                   TAB2:
-------------           ---------------
NO                      ALPH
-------------           ---------------
1                       A
2                       B
3                       C
4                       D
5                       E
                        F
                        G输出结果:
--------------------------
NO        |ALPH
--------------------------
1          A
2          A
3          A
4          A
5          A
1          B
2          B
3          B
4          B
5          B
     .
     .
     .
1          G
2          G
3          G
4          G
5          G从以上的结果我认为这个结果是TAB2*TAB1的笛卡尔积的结果。
2.同样的SELECT语句:SELECT TAB1.NO,TAB2.ALPH FROM TAB1, TAB2;TAB1不变,TAB2将数据行减少TAB1:                   TAB2:
-------------           ---------------
NO                      ALPH
-------------           ---------------
1                       A
2                       B
3                       C
4
5                                             
                        
输出结果:--------------------------
NO        |ALPH
--------------------------
1          A
1          B
1          C
2          A
2          B
2          C
3          A
3          B
3          C
4          A
4          B
4          C
5          A
5          B
5          C以上的结果我认为是TAB1*TAB2的笛卡尔积的结果我想知道为什么同一个SELECT语句,根据表的内容不同,笛卡尔积反映出来显示结果会不同?其中有什么奥妙呢?                        

解决方案 »

  1.   

    呵呵,实际上,A*B, B*A,结果都是一样的,对不对。你所说的问题,实际上涉及到oracle存储数据的问题,因为在Oracle中,数据存储是无序的(有些数据库先插入的在不排序的情况下,会先被检索出来),
    这样,当表中的记录发生变更后,取记录的顺序就会发生变化,笛卡尔积也发生变化。你可以尝试一个表,在某些时候删除了一些行后,检索出的结果顺序也会发生改变。
      

  2.   

    >jinxfei
    谢谢你回答我的问题,我尝试了你所说的方法,的确和你说的情况一样。
    那么也就是说我们无法判断笛卡尔积查询的结果吗?还有A*B和B*A的问题,我觉得在整体上来看的确是相同的,但从局部来看,A*B是用A的第一行去和B的每一行结合,结合完毕后再用A的第二行和B的每一行结合,以此类推。而B*A是用B的第一行和A的每一行结合,结合完毕后再用B的第二行和A的每一行结合。如果按局部的结合顺序来看,我个人认为似乎并不相同。我觉得你说的意思是ORACLE在取数据记录的时候,是无序的。先把表里的数据全部都取来,然后再进行排序整列。
    但从结果来看,总是符合A*B或者B*A的结果顺序,ORACLE是怎么判断以何种方式输出结果的呢?都是同样的一个的SELECT文,实在让人很想不通……PS;我想是因为我没有看过数据库的底层实现内容,不了解实际的操作过程……*_*
      

  3.   

    楼主的问题以前没注意过如果要得出想要的结果还是
    order by一下吧
      

  4.   

    这个问题真是的,oracle 在对 from 关键字之后提到的表的处理是从右向左的,所以才有优化sql时将数据量小的表尽量排在右边,出现lz提到的现象也就没什么好大惊小怪的了。
      

  5.   

    不是说Oracle取数据无序,而是数据存储本身就无序,如果想明确顺序,就用order by。没有Order by,那就是取出一条匹配一条,也就没有什么顺序可言了。但你说的也是对的,A*B和B*A结果的顺序肯定是有差异。