SQL面试题汇总_求职面试_非技术区_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 非技术区 > 求职面试 > SQL面试题汇总

SQL面试题汇总

 2010/12/14 9:55:30  358713428  http://358713428.javaeye.com  我要评论(0)
  • 摘要:规律:数字不用单引号,字符用单引号SQLSERVER分页语句select*fromt_loginorderbypk_iddesc;selecttop2*fromt_login;--随机selecttop3*fromt_loginorderbynewid();selecttop2*fromt_loginwherepk_idnotin(selecttop3pk_idfromt_loginorderbypk_iddesc)orderbypk_iddesc;MYSQL分页语句-
  • 标签:面试 面试题 SQL
规律:数字不用单引号,字符用单引号

SQLSERVER分页语句
select * from t_login order by pk_id desc;

select top 2 * from t_login;
--随机
select top 3 * from t_login order by newid();

select top 2 * from t_login where pk_id not in(
select top 3 pk_id from t_login order by pk_id desc)
order by pk_id desc;

MYSQL分页语句
--显示三条数据
Select * from t_login limit 3;
--显示从2开始的四条数据
Select * from t_login limit 2,4;

Oracle分页语句
--显示2条数据
Select * from t_login where rownum<=3;
--从100开始,到199号
Select * from (select * from t_login where rownum<=199) where rownum >=100;

选择
1. 假设有一个名为email_table 的表,包含名字和地址两个字段,要得到Bill Gates 的e_mail地址,你可以使用下面的查询:
SELECT email from email_table WHERE name=’Bill Gates’

2. 前面说过,查询可以在查询条件中包含逻辑运算符。假如你想读取Bill Gates 或Clinton总统的所有email地址,你可以使用下面的查询语句
SELECT  email  FROM  email_table  WHERE  name=’Bill Gates’ OR name=’president  Clinton’
(select name,email,[add] from name  where name='zhd') 单词不完整时,默认加[ ]

3. 你可以在一个SELECT语句中一次取出多个字段,比如:
SELECT au_fname ,au_lname, phone FROM authors
在SELECT语句中,你需要列出多少个字段,你就可以列出多少。不要忘了把字段名用逗号隔开。你也可以用星号(*)从一个表中取出所有的字段。这里有一个使用星号的例子
SELECT  *  FROM  authors
(SELECT  *  FROM  NAME,NAME1)

4. 你也可以用一个SELECT语句同时从多个表中取出数据,只需在SELECT语句的FROM从句中列出要从中取出数据的表名称即可:
SELECT  au_name,title FROM authors,titles,titleauthor
WHERE  authors.au_id=titleauthor.au_id
AND  titles.title_id=titleauthor.title_id

5. 要指明表titles和表publishers之间的关系,你只要让这两个表有一个公共的字段就可以了。在数据库pubs中,表titles和表publishers都有一个名为pub_id的字段。如果你想得到书名及其出版商的一个列表,你可以使用如下的语句:
SELECT  title,pub_name  FROM  titles,publishers
WHERE titles.pub_id=publishers.pub_id

6. 在SELECT语句中,你可以在缺省字段名后面仅跟一个新名字来取代它。例如,可以用一个更直观易读的名字Author Last Name来代替字段名au_lname:
SELECT au_lname ‘Author Last Name’ FROM authors
当这个SELECT语句执行时,来自字段au_lname的值会与“Author Last Name”相联系。查询结果可能是这样:
      Author Last Name
      White
      Green
      Carson
      O’Leary
      Straight
注意字段标题不再是au_lname,而是被Author Last Name所取代。

7. 如果你想把表titles中的所有书的价格加倍,你可以使用下面的SELECT语句:
SELECT  price*2 FROM titles      
当这个查询执行时,每本书的价格从表中取出时都会加倍。但是,通过这种途径操作字段不会改变存储在表中的书价。对字段的运算只会影响SELECT语句的输出,而不会影响表中的数据。为了同时显示书的原始价格和涨价后的新价格,你可以使用下面的查询:
SELECT  price  "Original  price", price*2  "New price" FROM  titles
当数据从表titles中取出时,原始价格显示在标题Original price下面,加倍后的价格显示在标题New price下面。结果可能是这样:
      original  price         new  price
19.99 39.98
11.95                 23.90
2.99 5.98
19.99 39.98
19.100
8. 你可以使用大多数标准的数学运算符来操作字段值,如加(+),减(-),乘(*)和除(/)。你也可以一次对多个字段进行运算,例如:
SELECT  price*ytd_sales ‘total revenue’ FROM titles
在这个例子中,通过把价格与销售量相乘,计算出了每种书的总销售额。这个SELECT语句的结果将是这样的:
      total  revenue
      81,859,05
      46,318,20
      55,978,78
      81,859,05
      40,619,68
     
最后,你还可以使用连接运算符(它看起来像个加号)来连接两个字符型字段:
SELECT  au_fname+’ ’+au_lname’author name’ FROM authors
(Select au_fname+au_lname’author name’ from authors)
这个语句的执行结果将是这样的:
       author  names
       Johnson White
       Marjorie Green
       Cheryl  Carson
      Michael O’Leary
      Dean Straight
      …
      (23 row(s)  affected)

排序
通过使用ORDER BY子句,你可以强制一个查询结果按升序排列,就像这样:
SELECT au_lname FROM  authors  ORDER  BY  au_lname
当这个SELECT语句执行时,作者名字的显示将按字母顺序排列。ORDER BY子句将作者名字按升序排列。
你也可以同时对多个列使用ORDER BY子句。例如,如果你想同时按升序显示字段au_lname和字段au_fname,你需要对两个字段都进行排序:
SELECT au_lname,au_fname FROM authors ORDER BY au_lname ,au_fname
这个查询首先把结果按au_lname字段进行排序,然后按字段au_fname排序。记录将按如下的顺序取出:
      au_lname                         au_fname
      …………………………………………………………………….
      Bennet                           Abraham
      Ringer                            Albert
      Ringer                            Anne
      Smith                             Meander
   
如果你想把查询结果按降序排列,你可以使用关键字DESC。
SELECT  au_lname,au_fname  FROM authors
WHERE au_lname=’Ringer’  ORDER BY  au_lname ,au_fname  DESC
这个查询从表authors中取出所有名字为Ringer的作者记录。ORDER BY子句根据作者的名字和姓,将查询结果按降序排列。结果是这样的:
      au_lname                          au_fname
      ……………………………………………………………………………………….
      Ringer                             Anne
      Ringer                             Albert
      (2 row(s)  affectec)
取出互不相同的值
一个表有可能在同一列中有重复的值。例如,数据库pubs的表authors中有两个作者的名字是Ringer。如果你从这个表中取出所有的名字,名字Ringer将会显示两次。
在特定情况下,你可能只有兴趣从一个表中取出互不相同的值。如果一个字段有重复的值,你也许希望每个值只被选取一次,你可以使用关键字DISTINCT来做到这一点:
SELCET  DISTINCT au_lname  FROM  authors   WHERE  au_lname=’Ringer’

警告:如同ORDER BY子句一样,强制服务器返回互不相同的值也会增加运行开销。不得不花费一些时间来完成这项工作。因此,不是必须的时候不要使用关键字DISTINCT。

创建表
在查询窗口中键入下面的SQL语句,单击执行查询按钮,执行这个语句:
CREATE  TABLE  guestbook (visitor VARCHAR(40),comments TEXT,entrydate DATETIME)
                                       
删除表和修改表
1. 要删除一个表,你可以使用SQL语句DROP TABLE。   
DROP TABLE mytable
警告:使用DROP TABLE命令时一定要小心。一旦一个表被删除之后,你将无法恢复它。
2.如果你想清除表中的所有数据但不删除这个表,你可以使用truncate TRUNCATE TABLE语句。
TRUNCATE TABLE mytable
3.虽然你不能删除和修改已经存在的字段,但你可以增加新字段。
ALTER TABLE mytable ADD mynewcolumn INT NULL
注意:ALTER TABLE 只允许添加可包含空值或指定了 DEFAULT 定义的列。

索引(有待深入理解
对于包含索引的数据库,SQL Sever需要一个可观的额外空间。例如,要建立一个聚簇索引,需要大约1.2倍于数据大小的空间。
索引有两种类型:聚簇索引和非聚簇索引。在聚簇索引中,索引树的叶级页包含实际的数据:记录的索引顺序与物理顺序相同。在非聚簇索引中,叶级页指向表中的记录:记录的物理顺序与逻辑顺序没有必然的联系。
聚簇索引非常象目录表,目录表的顺序与实际的页码顺序是一致的。非聚簇索引则更象书的标准索引表,索引表中的顺序通常与实际的页码顺序是不一致的。一本书也许有多个索引。例如,它也许同时有主题索引和作者索引。同样,一个表可以有多个非聚簇索引。
    通常情况下,你使用的是聚簇索引,但是你应该对两种类型索引的优缺点都有所理解。
    每个表只能有一个聚簇索引,因为一个表中的记录只能以一种物理顺序存放。通常你要对一个表按照标识字段建立聚簇索引。但是,你也可以对其它类型的字段建立聚簇索引,如字符型,数值型和日期时间型字段。
    从建立了聚簇索引的表中取出数据要比建立了非聚簇索引的表快。当你需要取出一定范围内的数据时,用聚簇索引也比用非聚簇索引好。例如,假设你用一个表来记录访问者在你网点上的活动。如果你想取出在一定时间段内的登录信息,你应该对这个表的DATETIME型字段建立聚簇索引。
    对聚簇索引的主要限制是每个表只能建立一个聚簇索引。但是,一个表可以有不止一个非聚簇索引。实际上,对每个表你最多可以建立249个非聚簇索引。你也可以对一个表同时建立聚簇索引和非聚簇索引。
    假如你不仅想根据日期,而且想根据用户名从你的网点活动日志中取数据。在这种情况下,同时建立一个聚簇索引和非聚簇索引是有效的。你可以对日期时间字段建立聚簇索引,对用户名字段建立非聚簇索引。如果你发现你需要更多的索引方式,你可以增加更多的非聚簇索引。
    非聚簇索引需要大量的硬盘空间和内存。另外,虽然非聚簇索引可以提高从表中 取数据的速度,它也会降低向表中插入和更新数据的速度。每当你改变了一个建立了非聚簇索引的表中的数据时,必须同时更新索引。因此你对一个表建立非聚簇索引时要慎重考虑。如果你预计一个表需要频繁地更新数据,那么不要对它建立太多非聚簇索引。另外,如果硬盘和内存空间有限,也应该限制使用非聚簇索引的数量。
这两种类型的索引都有两个重要属性:你可以用两者中任一种类型同时对多个字段建立索引(复合索引);两种类型的索引都可以指定为唯一索引。
1.非聚簇索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
注意:蓝色必填,索引名字
2.如果你需要改变一个索引的类型,你必须删除原来的索引并重建 一个。建立了一个索引后,你可以用下面的SQL语句删除它:
DROP INDEX mytable.mycolumn_index
聚簇索引:可以使用关键字CLUSTERED。
CREATE CLUSTERED INDEX mycolumn_clust_index ON mytable(mycolumn)
(旧版本:如果表中有重复的记录,当你试图用这个语句建立索引时,会出现错误。但是有重复记录的表也可以建立索引;你只要使用关键字ALLOW_DUP_ROW把这一点告诉SQL Sever即可:CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)
                     WITH ALLOW_DUP_ROW)
3.要对一个表建立唯一索引,可以使用关键字UNIQUE。对聚簇索引和非聚簇索引都可以使用这个关键字。这里有一个例子:
CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
4.要建立一个对多个字段的索引──复合索引──在索引建立语句中同时包含多个字段名。下面的例子对firstname和lastname两个字段建立索引:
CREATE INDEX name_index ON username(firstname,lastname)

添加 修改 删除数据
添加:向表中添加新记录
INSERT mytable (first_column,second_column,third_column)
        VALUES (‘some data’,’some more data’,’yet more data’)
你可以使用INSERT语句向文本型字段中插入数据。但是,如果你需要输入很长的字符串,你应该使用WRITETEXT语句(旧版本)。
如果你在INSERT 语句中只指定两个字段和数据会怎么样呢?换句话说,你向一个表中插入一条新记录,但有一个字段没有提供数据。在这种情况下,有下面的四种可能:
1.如果该字段有一个缺省值,该值会被使用。
2.如果该字段可以接受空值,而且没有缺省值,则会被插入空值。
3.如果该字段不能接受空值,而且没有缺省值,就会出现错误。
4.最后,如果该字段是一个标识字段,那么它会自动产生一个新值。当你向一个有标识字段的表中插入新记录时,只要忽略该字段,标识字段会给自己赋一个新值。
向一个有标识字段的表中插入新记录后,你可以用SQL变量@@identity来访问新记录
的标识字段的值。考虑如下的SQL语句:
INSERT mytable (first_column) VALUES(‘some value’)
INSERT anothertable(another_first,another_second)
         VALUES(@@identity,’some value’)
如果表mytable有一个标识字段,该字段的值会被插入表anothertable的another_first字段。这是因为变量@@identity总是保存最后一次插入标识字段的值。(查询最后一个)
注意:SET IDENTITY_INSERT 表名 Off ,当 IDENTITY_INSERT 设置为 OFF 时,不能向表 'book' 中的标识列插入显式值。 
      SET IDENTITY_INSERT 表名 on, 当 IDENTITY_INSERT 设置为 ON 时,必须指定表 'book' 中标识列的显式值。
删除:要从表中删除一个或多个记录,需要使用SQL DELETE语句。你可以给DELETE 语句提供WHERE 子句。WHERE子句用来选择要删除的记录。
DELETE mytable WHERE first_column=’goodby’ OR second_column=’so long’
如果你不给DELETE 语句提供WHERE 子句,表中的所有记录都将被删除。如果你想删除应该表中的所有记录,应使TRUNCATE TABLE语句。当你使用TRUNCATE TABLE语句时,记录的删除是不作记录的。也就是说,这意味着TRUNCATE TABLE 要比DELETE快得多。
修改:要修改表中已经存在的一条或多条记录,应使用SQL UPDATE语句。同DELETE语句一样,UPDATE语句可以使用WHERE子句来选择更新特定的记录。
UPDATE mytable  SET  first_column=’Updated!’
                     Second_column=’Updated!’
                     Third_column=’Updated!’
                 WHERE first_column=’Update Me1’
如果你不提供WHERE子句,表中的所有记录都将被更新。
注意:你可以对文本型字段使用UPDATE语句。但是,如果你需要更新很长的字符串,应使用UPDATETEXT语句。

Insert和select、update
有一个方法可以使INSERT 语句一次添加多个记录。
INSERT mytable (first_column,second_column)
SELECT another_first,another_second
FROM anothertable
WHERE another_first=’Copy Me!’
这个语句从anothertable拷贝记录到mytable.只有表anothertable中字段another_first的值为’Copy Me!’的记录才被拷贝。
如果你需要拷贝整个表,你可以使用SELECT  INTO 语句。
SELECT * INTO newtable FROM mytable
你也可以指定只有特定的字段被用来创建这个新表。
SELECT first_column INTO newtable
FROM mytable
WHERE second_column=’Copy Me!’
假设你想从一个表中删除一个字段。使用SELECT INTO 语句,你可以创建该表的一个拷贝,但不包含要删除的字段。这使你既删除了该字段,又保留了不想删除的数据。
如果你想改变一个字段的数据类型,你可以创建一个包含正确数据类型字段的新表。创建好该表后,你就可以结合使用UPDATE语句和SELECT 语句,把原来表中的所有数据拷贝到新表中。通过这种方法,你既可以修改表的结构,又能保存原有的数据。

其它常用表达式
1.假设你有一个表用来保存对你的站点进行民意调查的结果。现在你想向所有对你的站点的评价在7到10之间的访问者发送书面的感谢信。
SELECT username FROM opinion WHERE vote>6  and  vote<11
这个SELECT 语句会实现你的要求。你使用下面的SELECT 语句也可以得到同样的结果:
SELECT username FROM opinion WHERE vote BETWEEN 7 AND 10
2.现在假设你只想取出对你的站点投了1或者10的访问者的名字。要从表opinion中取出这些名字,你可以使用如下的SELECT 语句:
SELECT username FROM opinion WHERE vote=1 or vote=10
    这个SELECT语句会返回正确的结果,没有理由不使用它。但是,存在一种等价的方式。使用如下的SELECT可以得到相同的结果:
SELECT username FROM opinion WHERE vote IN (1,10)
注意表达式IN 的使用。这个SELECT 语句只取出vote的值等于括号中的值之一的记录。
3.你也可以使用IN来匹配字符数据。例如,假设你只想取出Bill Gates或President Clinton的投票值。
SELECT vote FROM opinion  WHERE  username IN (‘Bill Gates’,’President Clinton’)
4.你可以在使用BETWEEN或IN的同时使用表达式NOT。例如,要取出那些投票值不在7到10之间的人的名字,你可以使用如下的SELECT 语句:
SELECT username FROM opinion WHERE vote NOT BETWEEN 7 and 10
5.要选取那些某个字段的值不在一列值之中的记录,你可以同时使用NOT 和IN,如下例所示:
SELECT vote FROM opinion WHERE username NOT IN (‘Bill Gates’,’President Clinton’)

转换数据:在需要的时候可以把大部分数值从一种类型转换为另一种类型。
假设你想从一个MONEY型字段中取出所有的值,并在结果后面加上字符串“US Dollars”。你需要使用函数CONVERT()
SELECT CONVERT(CHAR(8),price)+ ‘US Dollars’ FROM orders
函数CONVERT()带有两个变量。第一个变量指定了数据类型和长度。第二个变量指定了要进行转换的字段。在这个例子中,字段price被转换成长度为8个字符的CHAR型字段。字段price要被转换成字符型,才可以在它后面连接上字符串’US Dollars’。
当向BIT型,DATETIME型,INT型,或者NUMERIC型字段添加字符串时,你需要进行同样的转换操作。例如,下面的语句在一个SELECT语句的查询结果中加入字符串’The vote is’,该SELECT语句返回一个BIT型字段的值:
SELECT ‘The vote is’+CONVERT(CHAR(1),vote) FROM opinion
下面是这个语句的结果示例:
The vote is 1
The vote is 1
The vote is 0

操作字符串数据
1.要把一个字符串与另一个字符串的一部分相匹配,你需要使用通配符。你使用通配符和关键字LIKE来实现模式匹配。取出包含关键字trading card的站点的列表
SELECT SITE_name FROM site_directory WHERE site_desc LIKE ‘%trading cark%’
百分号是通配符的例子之一。它代表0个或多个字符。
2. 目录分成更多页:
你想显示所有首字母在A到M之间的站点
SELECT site_name FROM site_directory WHERE site_name LIKE ‘[A-M]%’
你想显示所有首字母在N到Z之间的站点
SELECT site_name FROM  site_directory WHERE site_name LIKE ‘[N-Z]%’
3.你想显示那些以A,B或C开头的站点,
SELECT site_name FROM site_directory WHERE site_name LIKE  ‘[ABC]%’
4.你可以取出那些首字母在C到F之间,或者以字母Y开头的站点:
SELECT site_name FROM site_directory WHERE site_name LIKE ‘[C-FY]%’
5.你也可以使用脱字符(^)来排除特定的字符或字符范围。要得到那些名字不以Y开头的站点,
SELECT site_name FROM site_directory WHERE site_name LIKE ‘[^Y]%’
6.通过使用下划线字符(_),你可以匹配任何单个字符。例如,下面这个查询返回每一个其名字的第二个字符为任何字母的站点:
SELECT site_name FROM site_directory WHERE site_name LIKE ‘M_crosoft’
与通配符’%’不同,下划线只代表单个字符。
注意:如果你想匹配百分号或下划线字符本身,你需要把它们括在方括号中。如果你想匹配连字符(-),应把它指定为方括号中的第一个字符。如果你想匹配方括号,应把它们也括在方括号中。例如,下面的语句返回所有其描述中包含百分号的站点:
    SELECT site_name FROM site_directory WHERE site_desc LIKE ‘%[%]%’

Microsoft SQL 有两个允许你按照发音来匹配字符串的函数(没实际操作过)
1.函数SOUNDEX()给一个字符串分配一个音标码
如果你建立一个Internet目录,你也许想增加一个选项,允许访问者按照站点名的发音来搜索站点,而不是按名字的拼写。考虑如下的语句:
SELECT site_name FROM site_directory
                 WHERE DIFFERENCE(site_name , ‘Microsoft’>3)
这个语句使用函数DEFFERENCE()来取得其名字的发音与Microsoft非常相似的站点。函数DIFFERENCE()返回一个0到4之间的数字。如果该函数返回4,表示发音非常相近;如果该函数返回0,说明这两个字符串的发音相差很大。

2.函数DIFFERENCE()按照发音比较两个字符串
你可以用函数SOUNDEX()来返回函数DIFFERENCE()所使用的音标码。
SELECT site_name ‘site name’,SOUNDEX(site_name) ‘sounds like’
这个语句选取字段site_name的所有数据及其音标码。下面是这个查询的结果:
site name                     sounds like
……………………………………………………………….
Yahoo                         Y000
Mahoo                         M000
Microsoft                     M262
Macrosoft                     M262
Minisoft                      M521
Microshoft                    M262
Zicrosoft                     Z262

如果你仔细看一下音标码,你会注意到音标码的第一个字母与字段值的第一个字母相同。
函数DIFFERENDE()比较两个字符串的第一个字母和所有的辅音字母。该函数忽略任何元音字母(包括y),除非一个元音字母是一个字符串的第一个字母。
不幸的是,使用SOUNDEX()和DIFFERENCE()有一个欠缺。WHERE子句中包含这两个函数的查询执行起来效果不好。因此,你应该小心使用这两个函数。

删除空格
函数LTRIM()去除应该字符串前面的所有空格
函数RTRIM()去除一个字符串尾部的所有空格。
SELECT RTRIM(site_name) FROM site_directory
在这个例子中,如果任何一个站点的名字尾部有多余的空格,多余的空格将从查询结果中删去。
你可以嵌套使用这两个函数,把一个字符串前后的空格同时删去:
SELECT LTRIM(RTRIM(site_name)) FROM site_directory

日期和时间
1.通过函数GETDATE(),你可以获得当前的日期和时间。例如,语句SELECT GETDATE()返回如下的结果:
    NOV 30 1997 3:29AM
函数GETDATE()可以用来作为DATEDIME()型字段的缺省值。这对插入记录时保存当时的时间是有用的。例如,假设有一个表用来保存你站点上的活动日志。每当有一个访问者访问到你的站点时,就在表中添加一条新记录,记下访问者的名字,活动,和进行访问的时间。要建立一个表,其中的记录包含有当前的日期和时间,可以添加一个DATETIME型字段,指定其缺省值为函数GETDATE()的返回值,就象这样:
CREATE TABLE site_log (
       username VARCHAR(40),
       useractivity VARCHAR(100),
       entrydate DATETIME DEFAULT GETDATE())

函数GETDATE()的返回值在显示时只显示到秒。实际上,SQL Sever内部时间可以精确到毫秒级(确切地说,可以精确到3.33毫秒)。
要得到不同格式的日期和时间,你需要使用函数CONVERT()。例如,当下面的这个语句执行时,显示的时间将包括毫秒:
SELECT CONVERT(VARCHAR(30),GETDATE(),9)
注意例子中数字9的使用。这个数字指明了在显示日期和时间时使用哪种日期和时间格式。当这个语句执行时,将显示如下的日期和时间:
Nov 30 1997 3:29:55:170AM
在函数CONVERT()中你可以使用许多种不同风格的日期和时间格式。表11.1显示了所有的格式。
表11.1  日期和时间的类型
类型值            标准             输出
   0                 Default           mon dd yyyy hh:miAM
   1                 USA               mm/dd/yy
   2                 ANSI              yy.mm.dd
   3                 British/French    dd/mm/yy
   4                 German            dd.mm.yy
   5                 Italian           dd-mm-yy
   6                 -                 dd mon yy
   7                 -                 mon dd,yy
   8                 -                 hh:mi:ss
9                     Default + milliseconds--mon dd yyyy
hh:mi:ss:mmmAM(or )
   10                USA              mm-dd-yy
   11                JAPAN            yy/mm/dd
   12                ISO              yymmdd
   13                Europe           Default + milliseconds--dd mon yyyy
                                       hh:mi:ss:mmm(24h)
   14                 -                hh:mi:ss:mmm(24h)

   类型0,9,和13总是返回四位的年。对其它类型,要显示世纪,把style值加上100。类型13和14返回24小时时钟的时间。类型0,7,和13返回的月份用三位字符表示(用Nov代表November).

对表11.1中所列的每一种格式,你可以把类型值加上100来显示有世纪的年(例如,00年将显示为2000年)。例如,要按日本标准显示日期,包括世纪,你应使用如下的语句:
SELECT CONVERT(VARCHAR(30),GETDATE(),111)
   在这个例子中,函数CONVERT()把日期格式进行转换,显示为1997/11/30
2.当你分析表中的数据时,你也许希望取出某个特定时间的数据。你也许对特定的某一天中――比如说2000年12月25日――访问者在你站点上的活动感兴趣。要取出这种类型的数据,你也许会试图使用这样的SELECT语句:
SELECT * FROM weblog WHERE entrydate=’12/25/20000’
这个SELECT语句不会返回正确的记录――它将只返回日期和时间是12/25/2000 12:00:00:000AM的记录。换句话说,只有刚好在午夜零点输入的记录才被返回。
问题是SQL Sever将用完整的日期和时间代替部分日期和时间。例如,当你输入一个日期,但不输入时间时,SQL Sever将加上缺省的时间“12:00:00:000AM”。当你输入一个时间,但不输入日期时,SQL Sever将加上缺省的日期“Jan 1 1900”。
要返回正确的记录,你需要适用日期和时间范围。有不止一种途径可以做到这一点。例如,下面的这个SELECT 语句将能返回正确的记录:
SELECT * FROM weblog
WHERE  entrydate>=”12/25/2000” AND entrydate<”12/26/2000”
这个语句可以完成任务,因为它选取的是表中的日期和时间大于等于12/25/2000 12:00:00:000AM并小于12/26/2000 12:00:00:000AM的记录。换句话说,它将正确地返回2000年圣诞节这一天输入的每一条记录。
另一种方法是,你可以使用LIKE来返回正确的记录。通过在日期表达式中包含通配符“%”,你可以匹配一个特定日期的所有时间。这里有一个例子:
SELECT * FROM weblog WHERE entrydate LIKE ‘Dec 25 2000%’
这个语句可以匹配正确的记录。因为通配符“%”代表了任何时间。
使用这两种匹配日期和时间范围的函数,你可以选择某个月,某一天,某一年,某个小时,某一分钟,某一秒,甚至某一毫秒内输入的记录。但是,如果你使用LIKE 来匹配秒或毫秒,你首先需要使用函数CONVERT()把日期和时间转换为更精确的格式(参见前面“转换日期和时间”一节)。





五种常用的字段类型:字符型,文本型,数值型,逻辑性和日期型。
字符型:
1.VARCHAR类型可以存储的字符串最长为255个字符,存放可变长度的字符串信息。
2.CHAR指定了这个字段应该是固定长度的字符串。
3.VARCHAR型和CHAR型数据的这个差别是细微的,但是非常重要。假如你向一个长度为四十个字符的VARCHAR型字段中输入数据Bill Gates。当你以后从这个字段中取出此数据时,你取出的数据其长度为十个字符——字符串Bill Gates的长度。
现在假如你把字符串输入一个长度为四十个字符的CHAR型字段中,那么当你取出数据时,所取出的数据长度将是四十个字符。字符串的后面会被附加多余的空格。
VARCHAR型字段的另一个突出的好处是它可以比CHAR型字段占用更少的内存和硬盘空间。当你的数据库很大时,这种内存和磁盘空间的节省会变得非常重要。

文本型:
使用文本型数据,你可以存放超过二十亿个字符的字符串
无论何时,只要你能避免使用文本型字段,你就应该不适用它。文本型字段既大且慢,滥用文本型字段会使服务器速度变慢。文本型字段还会吃掉大量的磁盘空间。
警告:一旦你向文本型字段中输入了任何数据(甚至是空值),就会有2K的空间被自动分配给该数据。除非删除该记录,否则你无法收回这部分存储空间。

数值型:
1.INT型数据的表数范围是从-2,147,483,647到2,147,483,647的整数。
2.为了节省内存空间,你可以使用SMALLINT型数据。SMALLINT 型数据可以存储从-32768到32768的整数。这种数据类型的使用方法与INT型完全相同。
3.如果你实在需要节省空间,你可以使用TINYINT型数据。同样,这种类型的使用方法也与INT型相同,不同的是这种类型的字段只能存储从0到255的整数。TINYINT型字段不能用来存储负数。
注意:INYINT型数据只占用一个字节;一个INT型数据占用四个字节。
4.NUMERIC型数据使你能表示非常大的数——比INT型数据要大得多。一个NUMERIC型字段可以存储从-1038到1038范围内的数。NUMERIC型数据还使你能表示有小数部分的数。当定义一个NUMERIC型字段时,你需要同时指定整数部分的大小和小数部分的大小。这里有一个使用这种数据类型的例子:
CREATE TABLE numeric_data (bignumber NUMERIC(28,0), fraction NUMERIC (5,4) )
一个NUMERIC型数据的整数部分最大只能有28位,小数部分的位数必须小于或等于整数部分的位数,小数部分可以是零。
5.MONEY型数据可以存储从-922,337,203,685,477.5808到922,337,203,685,477.5807的钱数。如果你需要存储比这还大的金额,你可以使用NUMERIC型数据。
SMALLMONEY型数据只能存储从-214,748.3648到214,748.3647 的钱数。
SMALLMONEY型来代替MONEY型数据,以节省空间。
注意:除了numeric可以指定列宽之外,其他数据型不能指定列宽。

存储逻辑值:
BIT型字段只能取两个值:0或1。这里有一个如何使用这种字段的例子:
CREATE  TABLE  opinion (visitor VARCHAR(40),good BIT)
这个表可以用来存放对你的网点进行民意调查所得的信息。访问者可以投票表示他们是否喜欢你的网点。如果他们投YES,就在BIT型字段中存入1。反之,如果他们投NO,就在字段中存入0。
注意:在你创建好一个表之后,你不能向表中添加BIT型字段。如果你打算在一个表中包含BIT型字段,你必须在创建表时完成。

存储日期和时间:
为了能够存储日期和时间,你需要使用DATETIME型数据,如下例所示:
CREATE  TABL visitorlog( visitor VARCHAR (40), arrivaltime DATETIME ,
                               departuretime  DATETIME)
这个表可以用来记录访问者进入和离开你网点的时间和日期。一个DATETIME型的字段可以存储的日期范围是从1753年1月1日第一毫秒到9999年12月31日最后一毫秒。
如果你不需要覆盖这么大范围的日期和时间,你可以使用SMALLDATETIME型数据。它与DATETIME型数据同样使用,只不过它能表示的日期和时间范围比DATETIME型数据小,而且不如DATETIME型数据精确。一个SMALLDATETIME型的字段能够存储从1900年1月1日到2079年6月6日的日期,它只能精确到秒。
注意:不能指定列宽。
字段属性:控制空值,缺省值和标识值
允许和禁止空值:
空值(NULL)和零是不同的,严格的说,空值表示没有任何值。
例如,下面的表中两个字段都允许接受空值:
CREATE TABLE empty (empty1 CHAR (40) NULL,empty2 INT NULL)
注意:BIT型数据不能是空值。一个这种类型的字段必须取0或者1。
有时你需要禁止一个字段使用空值。例如,假设有一个表存储着信用卡号码和信用卡有效日期,你不会希望有人输入一个信用卡号码但不输入有效日期。为了强制两个字段都输入数据,你可以用下面的方法建立这个表:
CREATE TABLE creditcards (creditcard_number CHAR(20) NOT NULL,Creditcard_expire  DATETIME NOT NULL)

缺省值:(默认值)没填,保存时,自动生成默认值。
为了在创建一个表时指定缺省值,你可以使用表达式DEFAULT。请看下面这个在创建表时使用缺省值的例子:
CREATE TABLE addresses (street VARCHAR(60)  NULL,
                               city VARCHAR(40) NULL,
                               state VARCHAR(20) NULL,
                               zip  VARCHAR(20) NULL,
                               country VARCHAR(30) DEFAULT  ‘USA’)
在这个例子中,字段country的缺省值被指定为美国。注意单引号的使用,引号指明这是字符型数据。为了给非字符型的字段指定缺省值,不要把该值扩在引号中:
CREATE TABLE orders(price  MONEY DEFAULT $38.00,
                           quantity INT DEFAULT 50,
                            entrydate DATETIME DEFAULT GETDATE())
注意:DATETIME型字段entrydate所指定的缺省值,该缺省值是函数Getdate()的返回值,该函数返回当前的日期和时间。

标识字段:
每个表可以有一个也只能有一个标识字段。一个标识字段是唯一标识表中每条记录的特殊字段。为了建立一个标识字段,你只需在字段定义后面加上表达式IDENTITY即可。你只能把NUMERIC型或INT型字段设为标识字段,这里有一个例子:
CREATE TABLE visitorID (theID NUBERIC(18) IDENTITY,name VARCHAR(40))

1.2都是自动生成
技巧:建立一个标示字段时,注意使用足够大的数据类型。例如你使用TINYINT型数据,那么你只能向表中添加255个记录。如果你预计一个表可能会变得很大,你应该使用NUMERIC型数据。

五种类型的集合函数:统计记录数目,平均值,最小值,最大值,求和
统计记录数目:函数COUNT()也许是最有用的集合函数。
1.你可以用这个函数来统计一个表中有多少条记录。
SELECT COUNT(au_lname) FROM authors
这个例子计算表authors中名字(last name)的数目。如果相同的名字出现了不止一次,该名字将会被计算多次。
2.如果你想知道名字为某个特定值的作者有多少个,你可以使用WHERE子句,如下例所示:
SELECT COUNT(au_lname) FROM authors WHERE au_lname=’Ringer’
这个例子返回名字为’Ringer’的作者的数目。如果这个名字在表authors中出现了两次,则次函数的返回值是2。
3.假如你想知道有不同名字的作者的数目。你可以通过使用关键字DISTINCT来得到该数目。
SELECT COUNT(DISTINCT au_lname) FROM authors
如果名字’Ringer’出现了不止一次,它将只被计算一次。关键字DISTINCT 决定了只有互不相同的值才被计算。
通常,当你使用COUNT()时,字段中的空值将被忽略。一般来说,这正是你所希望的。但是,如果你仅仅想知道表中记录的数目,那么你需要计算表中所有的记录─不管它是否包含空值。
SELECT COUNT(*) FROM authors
注意函数COUNT()没有指定任何字段。这个语句计算表中所有记录所数目,包括有空值的记录。因此,你不需要指定要被计算的特定字段。
函数COUNT()在很多不同情况下是有用的。例如,假设有一个表保存了对你站点的质量进行民意调查的结果。这个表有一个名为vote的字段,该字段的值要么是0,要么是1。0表示反对票,1表示赞成票。要确定赞成票的数量,你可以所有下面的SELECT 语句:
SELECT COUNT(vote) FROM opinion_table WHERE vote=1
平均值:使用函数AVG(),你可以返回一个字段中所有值的平均值。
SELECT AVG(vote) FROM opinion
函数AVG()只能对数值型字段使用。这个函数在计算平均值时也忽略空值。
最小值:使用函数min(),你可以返回一个字段中所有值的最小值。
SELECT MIN(vote) FROM opinion
函数MIN()返回一个字段的所有值中的最小值。如果字段是空的,函数MIN()返回空值。
最大值:使用函数max(),你可以返回一个字段中所有值的最大值。
SELECT MAX(vote) FROM opinion
求和:使用函数sum(),你可以返回一个字段中所有值的和值。
SELECT SUM(purchase_amount) FROM orders



发表评论
用户名: 匿名