SQL基础语言
一.概述:
SQL是英文Structured Query Language的缩写,意思为结构化查询语言。SQL有两个特点:所有数据存储在表中;从SQL的角度来说,表中的记录没有顺序。
绝大多数流行的关系型数据库管理系统,采用了SQL语言标准。
二.数据定义:
1.创建表;
create table语句的使用格式如下:
create table tablename
(column1 data type [constraint],
column2 data type [constraint],
column3 data type [constraint]);
例子:
create table employee
(employee_id, IDENTITY //每个表可以有一个也只能有一个标识字段;
firstname varchar(15) NULL, //允许空值;
lastname varchar(20),
age number(3),
address varchar(30),
city varchar(20) DEFAULT‘USA’); //city缺省值被设置为美国;
简单来说,创建新表格时,在关键词create table后面加入所要建立的表格的名称,然后在括号内顺次设定各列的名称,数据类型,以及可选的限制条件等。注意,所有的SQL语句在结尾处都要使用“;”符号。
2.创建索引:
索引在表数据量大的地方增加方有效,有索引地方查询快,插入更新则慢些。索引有两种类型:聚簇索引和非聚簇索引。
(1).非聚簇索引:
CREATE INDEX mycolumn_index ON mytable (myclumn)
这个语句建立了一个名为mycolumn_index的索引。你可以给一个索引起任何名字,但你应该在索引名中包含所索引的字段名,这对你将来弄清楚建立该索引的意图是有帮助的。索引mycolumn_index对表mytable的mycolumn字段进行。这是个非聚簇索引,也是个非唯一索引。
如果你需要改变一个索引的类型,你必须删除原来的索引并重建一个。建立了一个索引后,你可以用下面的SQL语句删除它:
DROP INDEX mytable.mycolumn_index
(2).一个聚簇索引:
可以使用关键字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
这个语句建立了一个允许重复记录的聚簇索引。你应该尽量避免在一个表中出现重复记录,但是,如果已经出现了,你可以使用这种方法。
要对一个表建立唯一索引,可以使用关键字UNIQUE。对聚簇索引和非聚簇索引都可以使用这个关键字。这里有一个例子:
CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
3.数据类型:
序号 | 数据类型名称 | 定义标识 | 备注 |
1 | 日期时间型 | datetime(8B)/smalldatetime(4B) | 两者存储长度,时间范围,精度不同 |
2 | 整数型 | bigint(8B)/int(4B)/smallint(2B)/tinyint(1B) | |
3 | 精确数值型 | decimal(numeric)/ | decimal(p[,s]);p精度,s小数位数 |
4 | 近似数值型 | float(8B)/real(4B) | |
5 | 货币型 | money(8B)/smallmoney(4B)/ | 符号:¥、$、£等 |
6 | 位型 | bit | 只有0和1,输入0以为的其他值均当1看待 |
7 | 字符型 | char(固定长度)、varchar(可变长度)、text | 均为非Unicode型 |
8 | Unicode型 | nchar(固定长度)、nvarchar(可变长度)、ntext | 均为Unicode型 |
9 | 二进制数据型 | binary/varbinary/images | 常用于存储图像 |
10 | 特殊数据型 | cursor、uniqueidentifier、timestamp、table、sql_variant | |
用户自定义数据类型:创建:sp_addtype;查看:sp_help;命名:sp_rename'old','new';删除:sp_droptype |
4.删除数据库表、删除索引:
要删除数据库表(包括该表存储的所有记录),使用 DROP TABLE 命令: DROP TABLE table_name;要删除 SUPPLIER 表,使用下面语句: DROP TABLE SUPPLIER; DROP INDEX 命令用于删除一个索引: DROP INDEX index_name;
三.数据操作
1.添加新记录
一旦表创建完成(参阅 创建表),就可以用命令 INSERT INTO 向里面填充元组。
Insert语句的使用格式如下:
insert into tablename (first_column,...last_column) values (first_value,...last_value);
例如:
insert into employee (firstname, lastname, age, address, city) values (‘Li’, ‘Ming’, 45, ‘No.77 Changan Road’, ‘Beijing”);
你也许已经注意到,INSERT 语句与DELETE语句和UPDATE语句有一点不同,它一次只操作一个记录。然而,有一个方法可以使INSERT 语句一次添加多个记录。要作到这一点,你需要把INSERT 语句与SELECT 语句结合起来,象这样:
使用 INSERT ... SELECT 语句,你可以从一个或多个表中读取多个记录行,并将其快速地插入到一个表中。
INSERT INTO tblTemp2 (fldID)
SELECT tblTemp1.fldOrder_ID
FROM tblTemp1
WHERE tblTemp1.fldOrder_ID > 100;
INSERT mytable (first_column,second_column)
SELECT another_first,another_second
FROM anothertable
WHERE another_first=’Copy Me!’
当为一个表中的记录建立备份时,这种形式的INSERT 语句是非常有用的。如果你需要拷贝整个表,你可以使用SELECT INTO语句
SELECT * INTO newtable FROM mytable
2.更新记录
update语句的格式为:
update tablename
set columnname = newvalue [, nextcolumn = newvalue2...]
where columnname OPERATOR value [and|or column OPERATOR value];
例如:
update employee set age = age+1
where first_name= ‘Mary’and last_name= ‘Williams’;
使用update语句时,关键一点就是要设定好用于进行判断的where条件从句。
3.删除记录:
Delete语句的格式为:
delete from tablename
where columnname OPERATOR value [and|or column OPERATOR value];
例如:
delete from employee
where lastname = May;
在delete from关键词之后输入表格名称,然后在where从句中设定删除记录的判断条件。注意,如果用户在使用delete语句时不设定where从句,则表格中的所有记录将全部被删除。
四.数据查询
Select语句的完整语法格式如下:
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expression [ AS output_name ] [, ...] [ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ] [ FROM from_item [, ...] ] [ WHERE condition ] [ GROUP BY expression [, ...] ] [ HAVING condition [, ...] ] [ { UNION | INTERSECT | EXCEPT [ ALL ] } select ] [ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ] [ FOR UPDATE [ OF class_name [, ...] ] ] [ LIMIT { count | ALL } [ { OFFSET | , } start ]]
说明:用中括号([])括起来的部分表示是可选的,用大括号({})括起来的部分是表示必须从中选择其中的一个。
举例如下:
select firstname, lastname, city
from employee
where firstname LIKE ‘E%’;
上述SQL语句将会查询所有名称以E开头的姓名。
select * from employee
where firstname = ‘May’;
上述SQL语句将会查询所有名称为May的行。
在 SELECT语句里使用 "*" 将检索出表中的所有属性。
1. ALL、DISTINCT、DISTINCTROW、TOP谓词
(1) ALL 返回满足SQL语句条件的所有记录。如果没有指明这个谓词,默认为ALL。例:SELECT ALL FirstName,LastName FROM Employees (2) DISTINCT如果有多个记录的选择字段的数据相同,只返回一个。取出互不相同的记录,若要在以下的表格,Store_Info,找出所有不同的店名时:
SELECT DISTINCT store_name FROM Store_Info (3) DISTINCTROW 如果有重复的记录,只返回一个 (4) TOP显示查询头尾若干记录。也可返回记录的百分比,这是要用 TOP N PERCENT子句(其中N 表示百分比)例:返回5%定货额最大的定单SELECT TOP 5 PERCENT* FROM [ Order Details] ORDER BY UnitPrice*Quantity*(1-Discount) DESC
2. 为字段取别名方法
方法一:stuid as '编号'
方法二:stuid 编号 , stuid '编号' 都是正确的写法。
方法三:'编号' = stuid 同样单引号’也是可以省略的。
3.运算符(WH ERE子句)
查询功能 | 操作符 |
比较查询 | =、<、>、>=、<=、<>、!=、!<、!> |
范围查询 | BETWEEN……AND、NOT BETWEEN……AND |
列表查询 | IN、NOT IN |
字符串匹配查询 | LIKE、NOT LIKE |
空值判断查询 | IS NULL、IS NOT NULL |
逻辑判断查询 | AND、OR、NOT |
(1)操作运算用例:
你可以使用大多数标准的数学运算符来操作字段值,如加(+),减(-),乘(*)和除(/)。你也可以一次对多个字段进行运算,
SELECT price "Original price", price*2 "New price" FROM titles
(2)BETWEEN用例:
若我們要由 Store_Information 表格中找出所有介於 January 6, 1999 及 January 10, 1999 中的資料,
SELECT * FROM Store_Information WHERE Date BETWEEN 'Jan-06-1999' AND 'Jan-10-1999'
(3) IN用例:
IN 运算符用来匹配列表中的任何一个值。IN子句可以代替用OR子句连接的一连串的条件。
若我們要在 Store_Information 表格中找出所有含盖 Los Angeles 或 San Diego 的資料,
SELECT *FROM Store_Information WHERE store_name IN ('Los Angeles', 'San Diego')
(4)LIKE用法:
A、代表多个字符
‘* ’
c*c :代表cc,cBc,cbc,cabdfec等,它同于DOS命令中的通配符,代表多个字符;张* :代表查询以“张”字开头的记录;
*张 :代表查询以“张”字结尾的记录;
‘%’
%c%:代表agdcagd等;
张% :代表查询以“张”字开头的记录;
%张 :代表查询以“张”字结尾的记录;
通配符“*”与“%”的区别?
select * from table1 where name like '*明*'
select * from table1 where name like '%明%' 大家会看到,前一条语句列出来的是所有的记录,而后一条记录列出来的是name字段中含有“明”的记录,所以说,当我们作字符型字段包含一个子串的查询时最好采用“%”而不用“*”,用“*”的时候只在开头或者只在结尾时,而不能两端全由“*”代替任意字符的情况下。B、代表单个字符
‘?’
b?b代表brb,bFb等;同于DOS命令中的?通配符,代表单个字符
‘#’
k#k代表k1k,k8k,k0k ;大致同上,不同的是代只能代表单个数字
‘-’:代表一个字符
[a-z]代表a到z的26个字母中任意一个;指定一个范围中任意一个
‘[!字符]’
[!a-z]代表9,0,%,*等;它只代表单个字符
‘[!数字]’
[!0-9]代表A,b,C,d等;它只代表单个字符
(5)空值:
空值实际是指一种未知的、不存在或不可应用的资料,通常用NULL表示,NULL仅仅是一个符号,它不等于0也不等于空字符。
(6)OR或AND用例:
舉例來說,我們若要在 Store_Information 表格中選出所有 Sales 高於 $1,000 或是 Sales 在 $500 及 $275 之間的資料的話
SELECT store_name FROM Store_Information WHERE Sales > 1000 OR (Sales < 500 AND Sales > 275)
4. ORDER BY查询结果排序:
若我們要依照 Sales 欄位的由大往小列出 Store_Information 表格中的資料,
SELECT store_name, Sales, Date FROM Store_Information ORDER BY Sales,Date DESCASC:指定递增顺序;
DESC:指定递减顺序;
5.聚合函数用例:MAX、SUM、AVG、MIN、COUNT等
聚合函数是对表种的一组行的某个列进行计算并返回单个值的函数。聚合函数不能用在SELECT语句的WHERE子句中;聚合函数忽略空值;一个聚集对整个 SELECT 语句计算的结果是生成一个结果.但如果在一个查询里面声明了分组(GROUP BY),要让一个使用 GROUP BY 和聚集操作符的查询的结果有意义, 那么用于分组的属性也必须出现在目标列表中;数据库将对每个组进行一次独立的计算,并且 聚集结果是按照各个组出现的。还要注意的是在聚集上聚集是没有意义的,比如,AVG(MAX(sno))。
SUM 和 AVG 只能对数字列使用,例如 int、smallint、tinyint、decimal、numeric、float、real、money 和 smallmoney 数据类型;相反的, Min和Max就没有这么严格的限定, 它们可以操作那些实现了Icomparable的元素, 例如string,但不能对 bit 数据类型使用。除 COUNT(*) 外,其它聚合函数均不能对 text 和 image 数据类型使用。
Sum和Average操作必需是关于数值类型(int, long, float, double以及nullable版本),此外, Average总是返回decimal或者double两者之一:
1.如果选择器类型是decimal,则返回类型也是decimal
2.如果选择器类型是int, long, float, double, 则返回类型是double
这意味着下面的查询无法编译(因为double不能为自动转换为int)
1: int avg = new int[] { 3, 4 }.Average();
SELECT "函数名"("列名") FROM "表格名"
例如:SELECT SUM(Sales) FROM Store_Information
SELECT COUNT(au_lname) FROM authors WHERE au_lname=’Ringer’名字可重复
SELECT COUNT(DISTINCT au_lname) FROM authors 名字不重复,假如你投几票,也只记录到一票;
6. GROUP BY用例:
如果我们的需求变成是要算出每一间店 (store_name) 的营业额 (sales),
SELECT store_name, SUM(Sales) FROM Store_Information GROUP BY store_name
GROUP BY与ORDER BY区别?
答:在sql命令格式使用的先后顺序上,group by先于order by。 order by是按字段排序:order by 从英文里理解就是行的排序方式,默认的为升序。 order by 后面必须列出排序的字段名,可以是多个字段名。order by是按指定的列的升序或降序来给查询结果排序, 它不需要查询结果中出现order by的栏位。更改Order by里的栏位只影响查询结果的顺序,而不影响查询出的记录总数,和每条记录的内容。 group by是按字段分类:group by 从英文里理解就是分组。必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标志字段。使用group by 的目的就是要将数据分类汇总。group by是按指定的列对满足Where条件的所有记录分组,并对组内的一些数值型栏位计算出每组的一个统计指标,如求和、求个数、求平均值、求最大值、求最小值等等;它对查询结果有个要求:查询结果中的出现的栏位必须是Group by中栏位的子集。更改Group by里栏位的顺序不会对查询结果有任何影响;但是更改Group by的栏位,会对查询得到的记录数量,以及各个汇总函数的结果造成影响。
一般如: select 单位名称,count(职工id),sum(职工工资) form [某表]
group by 单位名称 这样的运行结果就是以“单位名称”为分类标志统计各单位的职工人数和工资总额。6. HAVING用例:
若我們要找出 Sales 大於 $1,500 的 store_name,我們就鍵入,
SELECT store_name, SUM(sales) FROM Store_Information GROUP BY store_name HAVING SUM(sales) > 1500
HAVING与WHERE区别?
答:HAVING只能与SELECT语句一起使用,通常在GROUP BY 子句中使用它,如果不使用GROUP BY子句,则HAVING的作用与WHERE子句一样。HAVING子句中不能使用text、image和ntext数据类型列项。与WHERE子句不同的是,在HAVING子句中可以使用聚合函数。
如果我们想知道那些销售超过一个部件的供应商,使用下面查询:
SELECT S.SNO, S.SNAME, COUNT(SE.PNO) FROM SUPPLIER S, SELLS SE WHERE S.SNO = SE.SNO GROUP BY S.SNO, S.SNAME HAVING COUNT(SE.PNO) > 1;在 WHERE 和 HAVING 子句里,允许在任何要产生数值的地方使用子查询 (子选择)。 这种情况下,该值必须首先来自对子查询的计算,HAVING的作用将变成第二次筛选结果集。
如果我们想知道所有比名为 'Screw' 的部件贵的部件,我们可以用下面的查询:
SELECT * FROM PART
WHERE PRICE > (SELECT PRICE FROM PART WHERE PNAME='Screw');当我们检查上面的查询时会发现出现了两次 SELECT 关键字。 第一个在查询的开头 - 我们将称之为外层 SELECT - 而另一个在 WHERE 子句里面,成为一个嵌入的查询 - 我们将称之为内层 SELECT。 对外层 SELECT 的每条记录都必须先计算内层 SELECT。在完成所有计算之后, 我们得知名为 'Screw' 部件的记录的价格, 然后我们就可以检查那些价格更贵的记录了。
7. 操作多个表用例:
方法一:同时从表authors和表titles中取出数据:
SELECT au_lname ,title FROM authors, titles
看一下查询结果。你会发现一些奇怪的出乎意料的情况:作者的名字并没有和它们所著的书相匹配,而是出现了作者名字和书名的所有可能的组合,这也许不是你所希望见到的。
出了什么差错?问题在于你没有指明这两个表之间的关系。你没有通过任何方式告诉SQL如何把表和表关联在一起。由于不知道如何关联两个表,服务器只能简单地返回取自两个表中的记录的所有可能组合。
要从两个表中选出有意义的记录组合,你需要通过建立两表中字段的关系来关联两个表。要做到这一点的途径之一是创建第三个表,专门用来描述另外两个表的字段之间的关系。
表authors有一个名为au_id的字段,包含有每个作者的唯一标识。表titles有一个名为title_id的字段,包含每个书名的唯一标识。如果你能在字段au_id和字段title_id 之间建立一个关系,你就可以关联这两个表。数据库pubs中有一个名为titleauthor的表,正是用来完成这个工作。
SELECT au_name,title FROM authors,titles,titleauthor
WHERE authors.au_id=titleauthor.au_id
AND titles.title_id=titleauthor.title_id
方法二:SQL的内联接和外联接
表Table1 记录如下:
aID aNum1 a200501112 a200501123 a200501134 a200501145 a20050115表Table2 记录如下:
bID bName1 20060324012 20060324023 20060324034 20060324048 2006032408内联接:两个表存在主外键关系时常用内联接查询。内连接只连接匹配的行;
SELECT * FROM Table1 INNER JOIN Table2 ON No1=No2
结果如下:
aID aNum bID bName1 a20050111 1 20060324012 a20050112 2 20060324023 a20050113 3 20060324034 a20050114 4 2006032404(所影响的行数为 4 行)
左外联接:结果包括左表的所有行,如果左表的行在右表中没有匹配的行,则为空值 以左表记录为基准
包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
SELECT * FROM Table1 LEFT (OUTER可省) JOIN Table2 ON No1=No2
结果如下:
aID aNum bID bName1 a20050111 1 20060324012 a20050112 2 20060324023 a20050113 3 20060324034 a20050114 4 20060324045 a20050115 NULL NULL(所影响的行数为 5 行)
右外联接:和左外联接相反 以右表记录为基准
包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
SELECT * FROM Table1 RIGHT JOIN Table2 ON No1=No2
结果如下:
aID aNum bID bName1 a20050111 1 20060324012 a20050112 2 20060324023 a20050113 3 20060324034 a20050114 4 2006032404NULL NULL 8 2006032408(所影响的行数为 5 行)
完全外联接:返回左表和右表中的所有行(FULL JOIN)
包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。其相互之间无匹配关系的字段全部显示为null.
SELECT * FROM Table1 FULL JOIN Table2 ON No1=No2
结果如下:
aID aNum bID bName1 a20050111 1 20060324012 a20050112 2 20060324023 a20050113 3 20060324034 a20050114 4 2006032404NULL NULL 8 20060324085 a20050115 NULL NULL
(所影响的行数为 6行)
交叉联接:返回的行数是左表与右表行数的乘积(CROSS JOIN)
SELECT *FROM table1 CROSS JOIN table2;
8.联合查询
Union, Intersect, Except(联合,相交,相异)三者用法一样。
UNION
用于将多个 SELECT
语句的结果联合到一个结果集中。例如:
(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10)
ORDER BY a;
下面是相交( INTERSECT)的例子: SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO > 1 INTERSECT SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO < 3;
最后是一个 EXCEPT 的例子: SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO > 1 EXCEPT SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO > 3;
9. CUBE和ROLLUP区别
CUBE运算符:在GROUP BY子句中包含CUBE选项时,查询结果不仅包含由GROUP BY提供的正常行,还包含对查询结果进行汇总统计;CUBE和ROLLUP之间的区别在于: CUBE 生成的结果集显示了所选列中值的所有组合的聚合。
ROLLUP生成的结果集显示了所选列中值的某一层次结构的聚合 ROLLUP就是将GROUP BY后面的第一列名称求总和,而其他列并不要求而CUBE则会将每一个列名称都求总和
例如:首先用ROLLUP
查询语句:
Select cust_id,product_code,sum(qty) as quantity
From invoices Where cust_id IN (4,5)
Group Bycust_id, product_code
WITH Rollup
Order By cust_id
查询结果: cust_id product_code quantity ------- -------------- ------- NULL NULL 10 4 5 3 4 6 3 4 NULL 6 5 5 4 5 NULL 4第一行是4,5买的所有产品的数量第二行是4买5产品的数量第三行是4买6产品的数量第四行是4买所有产品的数量第五行是5买5产品的数量第六行是5买所有产品的数量
如果查询语句中的ROLLUP关键字更改为CUBE,就会多出有关产品的信息查询结果: cust_id product_code quantity ------- -------------- ------- NULL NULL 10 NULL 5 7 NULL 6 3 4 5 3 4 6 3 4 NULL 6 5 5 4 5 NULL 4第2行是所有顾客买5产品的数量第3行是所有顾客买6产品的数量 ROLLUP操作的结果集具有类似 COMPUTE BY所返回结果集的功能;然而ROLLUP 具有下列优点: ROLLUP返回单个结果集;COMPUTE BY返回多个结果集,而多个结果集会增加应用程序代码的复杂性。 ROLLUP可以在服务器游标中使用;COMPUTE BY不可以。
使用COMPUTE子句和聚合函数也可以实现对数据库的统计操作,它与GROUP BY子句统计方法的区别是:它不仅显示统计结果,而且还显示各统计项目的明细资料,但它所返回的资料由多个结果集合组成。
五.其他
1.大小写问题:
注意:尽管在 Windows 中数据库与表名是忽略大小写的,你不应该在同一个查询中使用不同的大小写来引用一个给定的数据库和表。下面的查询将不能工作,因为它以 my_table 和 MY_TABLE 引用一个表:
SELECT * FROM my_table WHERE MY_TABLE.col=1;
列名与列的别名在所有的情况下均是忽略大小写的。
表的别名是区分大小写的。下面的查询将不能工作,因为它用 a 和 A 引用别名:
SELECT col_name FROM tbl_name AS a
WHERE a.col_name = 1 OR A.col_name = 2;
如果记忆数据库和表名的字母大小写有困难,建议采用一个一致一约定,例如总是以小写字母创建数据库和表。
2.关于主键、外键及标识
主键是建立在一个表内的a、主键不允许空值。b、一个表只能有一个主键,其余可以设置为候选键。c、表中可以无主键。d、表中设置主键的表中数据行不能重复。e、可以将表中的两行组合作为一个主键。用于强制表的实体完整性。
外键是建立在两个表之间关系的,具体操作为:在设计表窗口中 “属性”―― “关系”―― “新建”――在主键表中选择“borrow”,在外键表中选择“RID”所在表,然后在“主键表”下面的下拉列表中选择“RID”,在“外键表”下面的下拉列表中选择“RID”。
外键的好处就是在于 你企图插入一个child的时候 他会自动检测其parent是否存在 如果不存在 就不给你插入 保证数据中不会出现孤儿;
外键则是在其他表中引用另一个表的主键的字段叫外键,如人的银行卡记录可能有多条,每条都会有你的身份证号码、银行帐号。身份证号码就可以作为个人信息表的外键
列标识可以作为主键,但是也可以不作为主键,但是它可以判断一行的唯一性;标识设置后,id会自动给一个值。alter table tablename add id int identity(1,1)
有列标识才有标识种子,上面的1就是标识种子,标识就是由数字组成的一个序列,它的标识种子就是序列的开始值,标识递增量就是它的步长。标识:也具有唯一标志的作用,但他可以为空。
3. HANDLER
句法
HANDLER
是一个稍微低级的语句。举例来说,它不提供一致性约束。更确切地说,HANDLER ... OPEN
不 接受一个表的快照,并且 不 锁定表。这就意味着在一个 HANDLER ... OPEN
被执行后,表数据仍会被 (这个或其它的线程) 修改,这些修改可能在 HANDLER ... NEXT
和 HANDLER ... PREV
扫描中才会部分地出现。
4.
修改表格结构:
ALTER TABLE
句法:
在已经存在的表中增加或者移除字段
在列 d
上增加一个索引,将列 a
设为主键:
ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
移除列 c
:
ALTER TABLE t2 DROP COLUMN c;
添加一个名为 c
的 AUTO_INCREMENT
整型列:
ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD INDEX (c);
5.RENAME TABLE 句法
改名是从左到右执行的,这就意味着,如果你希望交换两个表名,你不得不这样做:
RENAME TABLE old_table TO backup_table,
new_table TO old_table,
backup_table TO new_table;
6.USE 句法
USE db_name 语句告诉 MySQL 使用 db_name 数据库作为以后查询的缺省数据库。数据库保持为当前数据库,只到该会话结束或另一个 USE 语句发出:
mysql> USE db1;
mysql> SELECT COUNT(*) FROM mytable; # 从 db1.mytable 中选择
mysql> USE db2;
mysql> SELECT COUNT(*) FROM mytable; # 从 db2.mytable 中选择
依靠 USE 语句将一个特定数据库设为当前数据库,它并不阻止你访问另一个数据中的表。下面的示例访问 db1 数据库中的 author 表和 db2 数据库中的 editor 表:
mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
-> WHERE author.editor_id = db2.editor.editor_id;
7.DESCRIBE 句法 (获得列的信息)
{DESCRIBE | DESC} tbl_name [col_name | wild]
DESCRIBE 提供有关一个表的列信息。col_name 可以是一个列名或是一个包含 SQL 通配符字符 “%” 和 “_” 的字符串。
8.转换数据用例:
假设你想从一个MONEY型字段中取出所有的值,并在结果后面加上字符串“US Dollars”。你需要使用函数CONVERT(),如下例所示:
SELECT CONVERT(CHAR(8),price)+’US Dollars’ FROM orders
9.匹配发音用例:
Microsoft SQL 有两个允许你按照发音来匹配字符串的函数。函数SOUNDEX()给一个字符串分配一个音标码,函数DIFFERENCE()按照发音比较两个字符串。当你不知道一个名字的确切拼写,但多少知道一点它的发音时,使用这两个函数将有助于你取出该记录。
例如,如果你建立一个Internet目录,你也许想增加一个选项,允许访问者按照站点名的发音来搜索站点,而不是按名字的拼写。考虑如下的语句:
SELECT site_name FROM site_directory
WHERE DIFFERENCE(site_name , ‘Microsoft’>3
函数DIFFERENCE()返回一个0到4之间的数字。如果该函数返回4,表示发音非常相近;如果该函数返回0,说明这两个字符串的发音相差很大。
10.删除空格用例:
有两个函数,TTRIM()和LTRIM(),可以用来从字符串中剪掉空格。函数LTRIM()去除应该字符串前面的所有空格;函数RTRIM()去除一个字符串尾部的所有空格。这里有一个任何使用函数RTRIM()的例子:
SELECT RTRIM(site_name) FROM site_directory
在这个例子中,如果任何一个站点的名字尾部有多余的空格,多余的空格将从查询结果中删去。
你可以嵌套使用这两个函数,把一个字符串前后的空格同时删去:
SELECT LTRIM(RTRIM(site_name) FROM site_directory
11.赋值问题:
在语句中除了 SET 之外还可以直接为一个变量赋值。然而在这各情况下,赋值操作符为 := 而不是 =,因为 = 在非 SET 语句中是用于比较的:
SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
12.返回当前日期:
通过函数GETDATE(),你可以获得当前的日期和时间。例如,语句SELECT GETDATE()返回如下的结果:
……………………………..
NOV 30 1997 3:29AM
(1 row(s) affected)
要得到不同格式的日期和时间,你需要使用函数CONVERT()。例如,当下面的这个语句执行时,显示的时间将包括毫秒:
SELECT CONVERT(VARCHAR(30),GETDATE(),9)
注意例子中数字9的使用。这个数字指明了在显示日期和时间时使用哪种日期和时间格式。当这个语句执行时,将显示如下的日期和时间:
…………………………………..
Nov 30 1997 3:29:55:170AM
(1 row(s) affected)
表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).
抽取日期:假设你想列出你的站点目录中每个站点被查询的月份。这时你不希望完整的日期和时间把网页弄乱。为了抽取日期的特定部分,你可以使用函数DATEPART(),象这样:
SELECT site_name ‘Site Name’,
DATEPART(mm,site_entrydate) ‘Month Posted’ FROM site_directory
函数DATEPART()的参数是两个变量。第一个变量指定要抽取日期的哪一部分;第二个变量是实际的数据。在这个例子中,函数DATEPART()抽取月份,因为mm代表月份。下面是这个SELECT 语句的输出结果:
Site Name Month Posted
………………………………………………………………
Yahoo 2
Microsoft 5
Magicw3 5
(3 row(s) affected)
表11.2 日期的各部分及其简写
日期部分 简写 值
year yy 1753--9999
quarter qq 1--4
month mm 1--12
day of year dy 1--366
day dd 1--31
week wk 1--53
weekday dw 1--7(Sunday--Saturday)
hour hh 0--23
minute mi 0--59
second ss 0--59
milisecond ms 0--999