经常会碰到这样一个问题,石凳论坛数据库里面有一个"用户资料"表,里面存储着用户的QQ号码、MSN、Email,等等记录,然后肯定还有一张"发贴记录"表(这张表显然非常大,包含所有的帖子),每次用户发贴的时候,都会保存这个用户的发贴标题,发贴内容和用户名。好,现在问题来了,需不需要为发贴记录这张表添加一些另外的列呢,比如说用户的QQ号。假如"发贴记录"表不含QQ号这个资料会是如何呢?现在就以QQ为例,假设我们需要查找174270这个QQ号所发的所有帖子,该如何查询?显然无法直接查询,因为"发贴记录"这张表中本身并不包含QQ这一列,因为QQ这一列是在"用户资料"那张表里面的。当然,我们可以在"发贴记录"里硬加QQ号码这一列。这样我们就可以完成查询操作,但是,QQ是解决了,那Email怎么办?MSN怎么办?等等等等...... 不可能每发一贴就要记录下这么多信息吧!如此一来数据库将会膨胀得惊人,显然这个办法也太笨了点。
如果把SELECT 子查询作为列名,问题将会迎刃而解:
SELECT Main.帖子标题, Main.发贴人,
(SELECT QQ号
FROM AS UserLib
WHERE Main.发贴人 = UserLib.发贴人) AS QQ号码
FROM 发贴记录 AS Main
发贴记录和用户资料这两张表,有一个关联,那就是发贴人,两张表都有这列,在用户资料表里面,发贴人列还是唯一的、不重复的。 我们采用两个别名Main 和 UserLib (FROM 子句后面加AS XXX可以自定义列的别名)
整个语句返回三列,
分别是:帖子标题,发贴人,QQ号码
其中帖子标题和发贴人是从发贴记录里面检索到的,而QQ号这一列则是由另一个SELECT语句派生出来的,第二个SELECT将Main表和UserLib表中的用户名相吻合起来,并返回QQ号码。
注意第二个SELECT检索的是数据库中的"QQ号",但是返回成列的时候却是"QQ号码",这个地方又启用了AS,别名在很多地方都有用,简单来说可以简化语句,看起来不那么眼花。更重要的是,在某些感知型数据控件内,比如说DBGrid,他们自动检索数据库里面的列并自动显示。有的时候,特别是排版的时候,就不喜欢采用数据库内部的列名,这个时候可以用AS自定义别名,比如数据库内存有一个"用户编号"的列,可实际排版的时候四个字太长了一屏显不下,那么SELECT 用户编号 AS 编号,即可。