SQL功能 | 操作符 | 运用方法 |
---|---|---|
数据定义 | CREATE,ALTER,DROP | 各个命令关键字后应紧跟所要定义的对象关键字,数据库为DATABASE、表为TABLE、视图为VIEW、索引为INDEX。 |
数据查询 | SELECT | |
数据操纵 | INSERT,UPDATE,DELETE | |
数据控制 | GRANT,REVOKE |
基本数据类型
字符串型:
- char(n):固定长度的字符串;
- varchar(n):可变长字符串
数值型:
- int:整数
- smallint:短整数类型
- numeric(p,d):定点数,由p位数字组成,小数点后边d位;
- real:浮点数,取决于机器的精度
- double precision:双精度浮点数,取决于机器精度
时间型:
- date:日期(年、月、日) ;1990-5-1
- time:时间(小时、分、秒);15:23:07
- interval:两个date或time类型数据之间的差
具体操作
增删改
创建数据库
CREATE DATABASE <数据库名>
[AUTHORIZATION <用户名> ]
删除数据库
DROP DATABASE 数据库名 [casade|restrict]
casade(连锁式):即执行DROP时,把SQL数据库及其下属的基本表、视图、索引等元素全部撤销
Restrict(约束式):只有当SQL数据库下面没有任何下属元素时,才能够撤销SQL数据库,否则不可以撤销。
创建数据表
create table SQL数据库名.基本表名(
列名 数据类型 [default 缺省值] [not null], --一个属性上的not null约束表明在该属性上不允许空值
primary key(列名 [,列名] …), --声明表示属性A₁,...,A.构成关系的主码,主码属性必须非空且唯一。
foreign key (列名 [,列名] …),REFERENCES --声明表示关系中任意元组在属性上(A₁,...,Am)上的取值必须对应于关系s中某元组的主码属性上的取值
references 表名 (列名 [,列名] …),
check(条件)]
)
Insert插入语句
指定所有列:
Insert into 仓库(仓库号,城市,面积,创建时间) values ('wh6','郑州','800','2005-12-01')
指定部分列
Insert into 仓库(仓库号,面积) values ('wh7',800)
Insert into 仓库 values ('wh7',null,800,null)
Insert into 仓库(仓库号,城市,面积,创建时间) values ('wh7',null,800,nul)
Delete删除语句
仅仅删除数据库表中的记录,不会删除表。不能删除单个列的值,而是删除整个记录。
Delete from 仓库 删除表中所有记录
Delete from 仓库 where 面积=’900’ 指定条件的删除语句
Update更新语句
Update 仓库 set 面积=面积+100 所有仓库的面积都增加100
Update 仓库 set 面积=面积+100 where 城市='上海' or 城市='北京' 把城市在上海或北京的仓库的面积增加100
查询
查询所有记录
Select * from 职工
投影查询
很多时候并不需要将所有列的数据都显示出来。投影查询就是允许用户显示所需要的列。假设显示职工表中职工号、姓名、工资信息,具体操作方法如下。
Select 职工号,姓名,工资 from 职工
在Select查询中,可以自定义显示列的顺序,如果要把姓名放到第一列,把语句顺序改成姓名, 职工号,工资即可
条件查询
显示wh1或wh2仓库、性别不为女、工资在1300~2100之间的职工信息。具体操作如下:
Select * from 职工号 where(仓库号='wh1' or 仓库号='wh2') And not 性别='女' and 工资>=1300 and 工资<=2100
在这里一定要注意,(仓库号=‘wh1’ or仓库号=‘wh2’)一定要加括号,否则就不是原题的意思。
In查询
在查找特定条件的数据时,如果条件较多,就需要用到多个Or运算符,以查找满足其中任一条的记录。但使用多个Or运算符,将使Where子句变得过于冗长,这时使用In就非常清楚。另外,在后面讲解的嵌套查询中,也必须使用In查询。
下面以zg1、zg2、zg11、zg15的订购单信息为例
Select * from 订购单 where 职工号 in ('zg1', 'zg2', 'zg11', 'zg15')
模糊查询
使用Like进行查询时,需要指定通配符
通配符 | 含义 |
---|---|
% | 包含0个或多个字符 |
_(下画线) | 包含一个字符 |
[] | 指定范围(如[a-z] |
[^] | 不属于指定范围([^a-z]) |
如果你知道姓名中含有“王”字,并且姓名只有两个字
Select * from 职工 where 姓名 like'王_'
空值查询
在SQL语句中使用IS NULL来进行是否为空的判断。下面以显示性别为空的职工信息为例具体讲解一下。
Select * from 职工 where 性别 is null
限制范围查询
当然可以使用大于等于号、小于等于号和And运算符三者来完成范围的限制,但使用Between…And结构,会使SQL更清楚。
下面以显示工资在1300~1900之间的职工信息为例
Select * from 职工 where 工资 Between 1300 And 19
消除重复字段数据查询
下面以显示职工的工资信息为例
Select 工资 from 职工 显示有重复的数据
Select Distinct工资 from 职工 显示无重复的数据
单表嵌套查询
就是外层Select语句与内层Select语句都来源于同一张表。
下面以显示仓库面积大于wh1仓库面积的仓库信息为例
首先利用Select语句求出wh1仓库的仓库面积,然后再显示面积大于该值的仓库信息
Select * from 仓库 where 面积 > (select 面积 from 仓库 where 仓库号='wh1')
嵌套查询中也可以带有逻辑运算符、谓词In、Like、Between…And结构。
多表嵌套查询
多表嵌套查询就是外层Select语句与内层Select语句来源于不同的表,但表之间要存在关系。这也是SQL语句中最重要的查询。
下面以显示北京地区的职工信息为例,首先利用Select语句求出北京地区的仓库号,然后利用仓库号再显示职工信息。
Select * from 职工 where 仓库号 in (select 仓库号 from where 城市='北京')
不仅可以实现两个表的嵌套,还可以实现多个表的嵌套,假设显示北京地区的职工的订购单信息。
首先利用Select语句得到北京地区的仓库号,然后利用得到的仓库号得到该仓库中的职工号,再利用得到的职工号得到职工的订购单信息。
Select * from 订购单 where 职工号 in(Select 职工号 from 职工 where 仓库号 in (select 仓库号 from 仓库 where 城市='北京'))
多表嵌套查询中也可以带有逻辑运算符、谓词In、Like、Between、And结构。假设显示北京地区的职工的订购单信息,并且职工的工资大于1200,订购日期为2003年9月3日~2006年1月1日。
Select * from 订购单 where 职工号 in(Select 职工号 from 职工 where 工资>1200 and 仓库号 in(select 仓库号 from 仓库 where 城市='北京')) and 订购日期 between '2003-09-03' and '2006-01-01'
单级排序查询
排序的关键字是Order by,默认状态下是升序,关键字是Asc。降序排列的关键字是Desc。排序字段可以是数值型,也可以是字符型、日期时间型。下面以按工资从高到低显示职工信息为例来讲解一下。
Select * from 职工 Order by 工资 desc
在排序查询中还可以带有逻辑运算符、谓词In、Like、Between、And结构。假设显示wh1或wh2仓库的,工资不大于职工zg16工资的职工信息,并要求职工姓名不含有“平”字,按工资从低到高显示。
首先利用Select语句求出职工zg16的工资,然后再对姓名进行模糊查询,最后再排序。
Select * from 职工 where 工资<=(Select 工资 from 职工 where 职工号='zg16') and 姓名 not like '%平%' and仓库号 in ('wh1','wh2') order by 工资
排序查询
按照一列进行排序后,如果该列有重复的记录值,则重复记录值这部分就没有进行有效的排序,这就需要再附加一个字段,作为第二次排序的标准,对没有排开的记录进行再排列。下面以按工资从高到低显示职工信息为例来讲解一下。
单级排序,按工资降序。
Select * from 职工Order by 工资 desc
多级排序,先按工资降序,再按职工ID升序。
Select * from 职工Order by 工资 desc,职工 ID asc
带有统计函数的嵌套查询
与别名一起使用的统计函数
在实际编程中,有时候需要知道所有记录某项值的总和、平均值、最大值等,这时就要用到统计函数查询。常用的统计函数共有6个。
统计函数及其意义
统计函数 | 含 义 |
---|---|
COUNT(*) | 统计选择的记录的个数 |
COUNT() | 统计特定列中值的个数 |
SUM() | 计算总和(必须是数值型字段) |
AVG() | 计算平均值(必须是数值型字段) |
MAX() | 确定最大值 |
NIN() | 确定最小值 |
在使用统计函数时,还要注意COUNT()、SUM()、AVG()可以使用DISTINCT关键字,以在计算机中不包含重复的行。而对于MAX()、MIN()、COUNT(*),由于不会改变其结果,因此没有必要使用DISTINCT。
利用Select语句显示统计值是没有列名的,下面以显示职工的最大值、最小值、工资总和、平均工资、职工人数为例来讲解一下。
Select max(工资),min(工资), SUM(工资),avg(工资),count(*) from 职工
这时会发现统计值没有列名,现在来给统计字段添加列名。
Select max(工资)as 最大工资,min(工资) as 最小工资, SUM(工资)as 工资总和,avg(工资)as 平均工资,count(*) as 职工人数 from 职工
在统计函数中还可以加条件,假设显示工资大于1500的职工的最大值、最小值、工资总和、平均工资、职工人数信息。
Select max(工资)as 最大工资,min(工资) as最小工资, SUM(工资)as 工资总和,avg(工资)as 平均工资,count(*) as 职工人数 from 职工 where 工资>1500
还可以利用统计函数得到的数据作为Select查询语句的条件进行查询。下面以显示工资大于所有职工平均值的职工信息为例来讲解一下。
Select * from table 职工where 工资>(select avg(工资) from 职工)
在统计函数查询中可以带有比较运算符、逻辑运算符、In、Between…And等。假设显示工资大于wh1或wh2仓库中职工平均工资,并且职工姓名不含有“亮”字的职工信息。
Select * from 职工where 工资>(select avg(工资) from 职工 where 仓库号='wh1' or 仓库号='wh2') and 姓名 not like '%亮%'
统计函数字段显示在表字段中及运算字段
如果在职工表中添加一个职工平均工资值字段,这就对实际编程有很大的意义,即可以利用平均字段进行运算,大大提高编程速度。下面以在职工表中添加平均工资为例为讲解一下。
Select 职工.*,(select avg(工资) from 职工) as 平均工资 from 职工
在职工表中添加了一个平均工资字段,即在Select查询字段中添加了一个Select子查询。
在Select查询中,还可以计算出每名职工的工资与所有职工平均工资之差,具体操作如下:
Select 职工.*,(select avg(工资) from 职工) as 平均工资,工资-(select avg(工资) from 职工) as 平均工资的差 from 职工
分组查询
使用GROUPBY分组查询,要注意分组的标准一定要有意义,如显示不同仓库的平均工资,显示不同职工的最大订单金额等。如果显示不同职工的平均工资那就没有意义了。下面显示不同仓库的平均工资、工资和、最大工资、最小工资、工资人数信息为例
Select 仓库号,max(工资)as 最大工资, min(工资)as 最小工资, sum(工资)as 工资总和, avg(工资)as 平均工资, count(*)as 职工人数 from 职工 group by 仓库号
在分组查询中还可以带有逻辑运算符、谓词In、Like、Between…And结构。假设显示工资大于zg1职工工资的不同仓库的平均工资、工资和、最大工资、最小工资、工资人数信息。
首先利用Select语句求出职工zg1的工资,然后再分组显示统计信息。
Select 仓库号,max(工资)as 最大工资, min(工资)as 最小工资, sum(工资)as 工资总和, avg(工资)as 平均工资, count(*)as 职工人数 from 职工 where 工资>(Select 工资 from 职工 where 职工号='zg1') group by 仓库号
带有Having的分组查询
分组以前的条件,要用Where关键字,而分组之后的条件则要使用Having关键字。下面以显示不同仓库的平均工资、工资和、最大工资、最小工资、工资人数信息,但要求该仓库平均工资大于1760为例来讲解一下。
Select 仓库号,max(工资)as 最大工资, min(工资)as 最小工资, sum(工资)as 工资总和, avg(工资)as 平均工资, count(*)as 职工人数 from 职工 group by 仓库号 having avg(工资)>1760
带有分组的嵌套查询
还可以利用分组得到的数据作为Select查询语句的条件进行查询。
下面以显示职工所在仓库的最大工资与最小工资之差在380~800之间的职工所在仓库信息为例为讲解一下。
先求出职工所在仓库的最大工资与最小工资之差在380~800之间的职工所在的仓库号,再利用这个仓库号显示仓库信息。
Select * from 仓库,where 仓库号 in(Select 仓库号 from 职工 group by 仓库号 having d max(工资)-min(工资) between 380 and 800
内外层嵌套实现分组功能
利用group by分组显示统计字段信息,有很多字段不能显示。如显示不同仓库的平均工资信息,在这个查询中只能显示仓库号,不能显示职工号及职工的工资。因为不同仓库的平均工资,有几个仓库就显示几条平均工资,而每个仓库中的职工则有很多。
下面以显示不同职工经手订购单金额最大的订单信息为例来讲解一下。
在这里应该边求出每名职工订购单金额的最大值,边显示该职工所对应的这条订购单信息。具体代码如下:
Select a.* from 订购单 a where 金额=( select max(金额) from 订购单 where 职工号=a.职工号)
注意:上面语句中的订购单 a是给这个订购单起的一个别名,大家可以把它看成就其实就是订购单的一张复制的表,在这里运用它只是为了使内外层的嵌套更清晰、更容易理解。
分组查询字段显示在表字段中及运算字段
如果在职工表中添加职工所在仓库的平均工资值字段,这就对实际编程有很大的意义,即可以利用平均字段进行运算,大大提高编程速度。下面以在职工表中添加职工所在的仓库的平均工资字段为例来讲解一下。
Select a.* ,(Select avg(工资) from 职工 where 仓库号=a.仓库号) as 所在仓库的平均工资 from 职工 a
在Select查询中,还可以计算出每名职工的工资与职工所在仓库的平均工资之差,具体操作如下:
Select a.* ,(Select avg(工资) from 职工 where 仓库号=a.仓库号) as 所在仓库的平均工资,工资-(Select avg(工资) from 职工 where 仓库号=a.仓库号) as 所在仓库的平均工资之差 from 职工 a
Exists谓词查询
其实In就是谓词查询,还有谓词Exists ,这两个谓词实现的功能是相同的,只是写法不同。In多用于嵌套子查询语句中,而Exists多用于判断Select语句是否返回查询结果。常用量词有Any、All和Some是同义词。在进行比较运算时,只要子查询中有一行能使结果为真,结果就为真。而All则要求子查询中所有行都使结果为真时,结果才为真。下面以显示那些仓库中还没有职工的仓库信息为例,讲解一下In谓词与Exists谓词在代码上的不同。
用Exists谓词实现:
Select * from 仓库 where not Exists(Select * from职工 where 仓库号=仓库.仓库号)
用In谓词实现:
Select * from 仓库 where 仓库号 not in(Select 仓库号 from 职工)
Any量词查询
Any量词查询,在进行比较运算时,只要子查询中有一行能使结果为真,则结果即为真。
下面就以显示工资大于等于wh2仓库中任一名职工工资的职工信息为例
用Any量词实现:
Select * from 职工 where 工资>=any(Select 工资 from 职工 where 仓库号='wh2')
使用统计函数实现:
Select * from 职工 where 工资>=(Select min(工资) from 职工 where 仓库号='wh2')
All量词查询
All量词查询,要求子查询中所有行都使结果为真时,结果才为真。
下面就以显示工资大于等于wh1仓库中所有职工工资的职工信息为例
用Any量词实现
Select * from 职工 where 工资>=All(Select 工资 from 职工 where 仓库号='wh1')
使用统计函数实现:
Select * from 职工 where 工资>=(Select MAX(工资)from 职工 where 仓库号='wh1')
前面讲解的量词查询都可以用统计函数代替,但有些查询是不能用统计函数代替的。
下面以显示工资大于所有不同仓库的平均工资的职工信息为例
Select * from 职工 where 工资>all(Select avg(工资)from 职工 group by 仓库号)
该题用统计函数就无法解决。
显示部分记录的Top查询
在编程中,有时只需显示满足条件的前几条记录,这时就可以使用Top关键字。可以直接使用Top数字,显示指定条数记录;也可以使用Top数字Percent,显示所有满足条件记录的前百分之几条记录。
下面以显示工资最高的前三条职工信息为例
Select top3 * from 职工 order by 工资 desc
保存查询
利用Into语句可以把查询的结果保存成一张新表。下面就以备份“职工”表为例讲解一下保存查询。
Select * into 职工备份 from 职工
这样就生成一张新表,表名为“职工备份”。
集合的并运算
可以将两个Selec语句的查询结果通过并运算合并成一个查询结果。
为了进行并运算,要求这样的两个查询结果具有相同的字段个数,并且对应的字段的值要出自同一个值域,即具有相同的数据类型和取值范围。
Select * from 仓库 where 城市='北京'
Union
Select * from 仓库 where 城市='上海'
集合的交运算
可以将两个Selec语句的查询结果通过交运算合并成一个查询结果。
为了进行交运算,要求这样的两个查询结果具有相同的字段个数,并且对应的字段的值要出自同一个值域,即具有相同的数据类型和取值范围。
Select 仓库号 from 仓库
Intersect
Select 仓库号 from 职工
注意它们对集合的差运算不支持。
多表连接查询
在进行多表连接时,一定要注意连接条件,下面以仓库表与职工表连接为例来讲解一下多表连接。
假设显示工资大于1500,面积大于600的城市与姓名信息。
Select 城市,姓名 * from 职工,仓库 where 职工.仓库号=仓库.仓库号 and 工资>1500 and 面积>600
超连接查询
超连接查询共有4种:内连接查询、左连接查询、右连接查询、全连接查询。使用超连接查询不仅可以把满足条件的记录显示出来,还可以把一部分不满足条件的记录以NULL显示出来。
内连接查询:只有满足连接条件的记录才出现在查询结果集中。
下面以显示面积大于600的仓库号、职工号、城市、面积、工资信息为例
Select 仓库.仓库号,职工号,城市,面积,工资 from 仓库 inner join 职工 on 职工.仓库号=仓库.仓库号 and 面积>600
左连接查询:除满足连接条件的记录显示外,第一张表中不满足条件的记录也出现在查询结果集中。
下面以显示面积大于600的仓库号、职工号、城市、面积、工资信息为例
Select 仓库.仓库号,职工号,城市,面积,工资 from 仓库 left join 职工 on 职工.仓库号=仓库.仓库号 and 面积>600
右连接查询:除满足连接条件的记录显示外,第二张表中不满足条件的记录也出现
在查询结果集中。下面以显示面积大于600的仓库号、职工号、城市、面积、工资信息为例
Select 仓库.仓库号,职工号,城市,面积,工资 from 仓库 right join 职工 on 职工.仓库号=仓库.仓库号 and 面积>600
全连接查询:除满足连接条件的记录显示外,两张表中不满足条件的记录也出现
在查询结果集中。下面以显示面积大于600的仓库号、职工号、城市、面积、工资信息为例
Select 仓库.仓库号,职工号,城市,面积,工资 from 仓库 full join 职工 on 职工.仓库号=仓库.仓库号 and 面积>600
多表超连接查询
如果是3张表或更多张表该如何实现超链接呢?
下面以显示面积大于600的仓库号、职工号、城市、面积、工资、金额信息为例
要显示的字段信息来源于3张表,仓库表、职工表、订购单表,这里实现仓库表与职工表的左连接,职工表与订购单表的右连接。
Select 仓库.仓库号,职工号,城市,面积,工资,金额 from 仓库 left join 职工 on 职工.仓库号=仓库.仓库号 right join 订购单 on 职工.职工号=订购单.职工号 and 面积>600