posts - 15,comments - 65,trackbacks - 0

          本文最新发布于http://www.lovestblog.cn,欢迎转载该文,但请注明文章出处,谢谢合作。 

          mysql的from从句用来指定参与查询的表,当然也可以是生成的中间表,在表前我们有时需要指定数据库,这主要是用在我们需要访问当前数据库之外的数据库中的表的情况,在这中情况下我们采用"."操作符来进行,如userdb.user,其实userdb为数据库名,user为表名,这是对mysql数据库而言的,对于DB2和Oracle就不是通过指定数据库名了,而是指定sql用户了,这就是说不同sql用户可以建立相同名字的表,但是同一个sql用户只能建立唯一名字的表。这就是它们在这表规范上面的区别。对于列规范,mysql可以在需要查询的列则可以采用如下形式进行访问:“数据库名.表名.列名”。对于多个表的规范,也就是涉及查询多个表的情况下,执行的过程是采用笛卡尔积的形式进行的。也就是说生成的中间表的列数为两个表中列数的总和,而行的总数等于一个表中的行的数量与另外一个表中行的数量的乘积。
       对于from从句中使用假名的情况,比如select u.id,name,age,a.account from utb as u,atb as a where u.id=a.user_id,在我们使用假名之后,那么在该sql语句的任何地方都只能使用假名,不能使用真实的表名,同时上面的as关键字也是可以省略的,也就是说对于上面的语句不能用atb来取代a,utb来取代u了。虽然from从句不是我们指定的第一条语句,但是绝对是第一个被处理的语句,所以在声明假名前使用假名不会导致错误。如果一条from从句引用到两个有着相同名称的表,则必须使用假名。如:

1select p.playerno
2from players as p,players as par
3where par.fn="jp" and par.ln="l" and p.birth_date<par.birth_date


       对于多个表间的连接处理可能会导致有相同的结果,即有重复的结果,sql并不会自动从最终结果中删除重复的行,这是如果我们不希望在结果中出现重复的行,那么我们可以在select后直接指定distinct。如:

1select distinct T.playerno 
2from teams as T,penalties as pen 
3where T.playerno=pen.playerno。

 

        接下来说说连接哈,对于内连接,如果是两个表的话,就取两个表的一个交集,如果是左外连接的话,那就是左边的表全取,右边没有的用null替代,弱国是右外连接的话,那就是右边的表全取,左边没有的用null表示。下面看看一个具体的例子:

1--表stu        --表exam 
2id name        id grade 
31, Jack         156 
42, Tom         276
53, Kity         1189
64, nono 

 

内连接 (显示两表id匹配的)

1select stu.id,exam.id,stu.name, exam.grade from stu (inner) join exam on stu.id=exam.id 
2-------------------------------- 
31 1 Jack 56 
42 2 Tom 76 

 

左连接(显示join 左边的表的所有数据,exam只有两条记录,所以stu.id,grade 都用NULL 显示)

1select stu.id,exam.id,stu.name, exam.grade from stu left (outer) join exam on stu.id=exam.id 
21 1 Jack 56 
32 2 Tom 76 
43 NULL Kity NULL 
54 NULL nono NULL 

 

右连接(与作连接相反,显示join右边表的所有数据)

1select stu.id,exam.id,stu.name, exam.grade from stu right join exam on stu.id=exam.id 
21 1 Jack 56 
32 2 Tom 76 
4NULL 11 NULL 89 

 

内连接取交集,外连接分左和右,
左连接左边的全取,
右连接右边的全取

      对于连接的列的名称相同的话,那么可以使用using来替代条件,如上面的内连接可以这样改写:
    

1  select stu.id,exam.id,stu.name, exam.grade from stu inner join exam using(id)。

      对于左外连接使用的情况一般是当左表的连接列中存在未出现在右表的连接列中的值时,左外连接才有用。
      还有个全外连接的,也就是说只要在两个表中出现的记录都会在中间表中出现,当右表有而左表没有或当左表有而右表没有的时候用null表示。具体语法如下:select stu.id,exam.id,stu.name, exam.grade from stu full join exam using(id)。
      交叉连接:就是显示求表的笛卡尔积,select * from teams cross join penalties.这句完全等价于select teams.*,penalties.* from teams,penalties.
      联合连接:select * from teams union join penalties,这个其实很容易理解,产生结果所包含的列为两个表所有的列和,对于数据的列出,首先列出左表的数据,对于属于右表的列,用null表示,接下来列出右表的数据,对于属于左表的列用null表示。
       自然连接:select * from teams nature inner join penalties where division='first';此句完全等同与select t.playerno,t.teamno,t.division,pen.paymentno,pen.payment_date,pen.amount from teams  as t inner join penalties as pen on t.playerno=pen.playerno where dividion='first'.相比就知道,我们无须显示指出必须要连接到哪些列,sql会自动查找两表中是否有相同名称的列,且假设他们必须在连接条件中使用。此处的on或using从句是多余的,因此不允许使用。

       下面看个例子创建一个称为towns的虚拟表:

1select *
2from (select 'Stratford' as town,4 as number 
3       union
4       select 'Plymouth',6
5       union
6       select 'Inglewood',1                 
7       union
8       select 'Douglas',2) as towns
9order by town;


结果为:

1town             number
2----------------------
3Douglas              2
4Inglewood           1
5Plymouth            6
6Stratford            4


 

posted on 2009-09-24 15:51 你假笨 阅读(2001) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: