前言
sql是用于访问和处理数据库的标准计算机语言。提供增、删、改、查、更新等语句。
SQL语法
记得在每条语句末尾加’;(分号)’。sql对大小写不敏感。
一切操作的前提都应该是该用户拥有该权限,才能执行命令。
如图:
意思就是create table t和create table T是一模一样的。对表t的操作和对表T的操作是一致的。
数据定义语言(DDL)
主要三大命令 CREATE(创建域,关系,视图都可以) , ALTER(修改只能修改关系) , DROP(删除域,关系,视图都可以)
定义数据库
创建数据库
(只有拥有CREATEDB权限的用户才可以创建新数据库)
注意 [] 表示可选可以出现 0 次或 1 次, {} 表示可重复出现出现 1 次以上, | 表示选择
/*owner表示数据库所有者,默认值是当前用户
*template表示模板名,即从哪个模板创建新数据库。默认值是template1
*encodeing表示数据库使用的字符编码,可以是UTF8等,默认值是模板数据库的编码
*/
CREATE DATABASE name
[[WITH]{[OWNER [=] user\_name]|
[TEMPLATE [=] template]|
[ENCODING [=] encoding]|[...]}[...]];
创建的数据库不能和已有数据库重名
修改数据库属性
可以包括名称,所有者,连接数限制,对象隔离属性等。
修改数据库的最大连接数。
ALTER DATABASE name
[[WITH] CONNECTION LIMIT connlimit];
修改数据库名称。
ALTER DATABASE name
rename to new_name;
修改的数据库名称不能和已有的数据库名称重
修改数据库所属者。
ALTER DATABASE name
OWNER TO new\_owner;
重置数据库配置参数
ALTER DATABASE database\_name RESET
{ configuration\_parameter | ALL };
删除数据库
只有数据库的所有者有权执行删除数据库命令。
DROP DATABASE [IF EXISTS] name;
注意drop database一旦执行将无法撤销,如果执行drop database失败,事务回滚,需要再次执行DROP DATABASE IF EXISTS
实操展示
定义模式
创建模式(CREATE SCHEMA)
语句与上述相似,但值得注意的是模式的名字不可以"pg_"开头,而且模式名不能和当前数据库中其他模式重名。
修改模式属性(ALTER SCHEMA)
与上述语句相似,如果修改模式的所有者,那么该成员必须在此数据库上有create权限,不然不行
删除模式(DROP SCHEMA)
只有模式所有者能发出drop schema命令
定义表空间
表空间名字不能和数据集群中的其他表空间重名,且名字不能以"pg"开头,这样的名字留给系统表空间使用。
定义表
它是在当前数据库创建一个空白表,该表由命令执行者所有。
支持一些完整性约束。
列约束:
not null:表明在该属性上不允许空值。
表约束(同时部分适用于列约束):
check:约束用于限制列中的值的范围。如check(x>0)
unique:约束唯一标识数据库表中每条记录。保证了结果唯一性,表中可以有很多个unique约束。
primary key:自动拥有了unique的约束,保证了结果唯一性。表中只能有一个primary key约束。
foreign key(A1,A2,…,An) references:一个表中的foreign key指向另一个表中的primary key。
创建表:
通用形式如下:
create table r
(列名1 数据类型1 \<列约束\>,
列名2 数据类型2 \<列约束\>,
...,
列名n 数据类型n \<列约束\>,
\<表约束1\>,
......,
\<表约束n\>)
例如:
修改表
可以修改表名,修改表中某一列的列名,可以修改表约束,设置表所属的模式,添加或者更新多个列等操作
例如:
修改表名
修改列名
添加列
修改列属性定义
修改表约束
设置主键
删除表
DROP TABLE会强制删除指定的表,删除表后,依赖该表的索引会被删除,而使用到该表的函数和存储过程将无法执行。
drop table name 和 delete from name
区别在于drop是直接删除了表,而delete是删除表中的所有元组,但是表还在。
如图:
基本运算
更名运算
有时候关系表或者属性名字很长或者难记可以进行更名,修改为简单的单个字母或者好记的英文单词。所以可以为属性更名也可为关系表更名。
更改属性名
更改关系名
字符串运算
在SQL中,字符串上的相等是大小写敏感的
upper(s)将字符串s转换为大写
lower(s)将字符串s转换为小写
使用like操作符来实现模式匹配
%:匹配任意子串
下划线_:匹配任意一个字符
xxx%:匹配以xxx开头的字符串
%xxx%:匹配含有xxx的字符串
'___'有多少根下划线,就匹配只有多少个字符的字符串
'___%'有多少根下划线,就匹配至少含有多少个字符的字符串
string_agg函数实现字段合并
排序元组的显示次序(order by)
有时候输出的时候想让查询结果按元组排序顺序输出,而不是按插入顺序输出。
那么就用到order by子句 其中order by子句默认使用升序,如果想要降序输出,那么久用 desc 表示降序
升序:(可以省略asc,也可以写出来跟在order by中的属性后面)
集合运算
并运算
union,将两个查询语句的结果 union ,它会 自动去重复 ,如果 不去重复 就应该 用** union all**代替union
它适用于 多个表 中 查询出相同结构的数据 ,并且 返回一个结果集
这里没有区分多表,如果想 区分多表 就在select处加如下:
也适用于 单个表中多次select查询 ,将结果 合并成一个结果集 返回
注意的是使用union结果查询时,只可以用一条order by子句对结果集进行排序,出现在最后一条select语句的右括号后面,只针对结果进行排序
交运算
找出在A语句找到的元组也在B语句找到的元组,两条语句调换结果,结果一样
intersect 同样的它也会结果 自动去重复, 想要保留重复就 intersect all 代替intersect
差运算
找出在A语句的元组但是不在B语句的元组,注意如果两条语句调换位置,结果不一样。
except** 结果去自动去重,想要保留重复就except all代替except
语句调换位置
空值
因为这个值null不知道代表什么,sql将涉及空值的任何比较运算的结果视为unknown
运算:
false and true= false | false or true = true
unknown and true = unknown | unknown or true = true
unknown and false = false | unknown or false = unknown
not unknown = unknown | not true = false | not false = true
同样的null=null会返回unknown
聚集函数
基本聚集
平均数:avg
最小值:min
最大值:max
总和:sum
计数:count
(不允许在用count(*)时使用distinct,但是在用min和max时可以)
分组聚集
group by 可以按照给的属性分组出结果
错误查询:
如上述class_name,student_id 没有在聚集,而且没有在group by中出现,这样子贸贸然在select出现是不对的是报错的。
having 子句:
!having子句在形成分组后才起作用
数据操作语言(DML)!重点
对表的操作
查询数据
主要由select,from和where子句构成
select 子句后跟需要结果投影出的属性名
from子句后跟哪张表
where 子句后跟选择的条件是什么
理解查询所代表的运算顺序是 先from再where最后是select
单关系查询
select 属性 from 表名;
(其中*表示全部)
可用 all 来显示指明不去除重复:
在select 后 加入关键词 distinct ,可以 去除重复 :
select子句还可以带 含有 + , - , \ , / 运算符 的算术表达式:
where子句允许我们只 选出 那些在from子句的结果关系中 满足特定条件的元组 。
如:现在我要查询"id是4002在tt表中的content",查询如下:
where 后的条件可以跟 and , or , not , between and 。
多关系查询
通常查询是需要从多个关系中获取信息的,所以需要多关系查询。
经典的SQL查询具有如下形式:
select A1,A2,....,An
from r1,r2,....,rn
where p;
/\*Ai代表一个属性,ri代表一个关系,p代表条件,如果省略p,就默认where true\*/
from子句是定义了一个在该子句中列出关系上的笛卡尔积。如果用迭代过程来理解即:
for each 元组t1 in 关系r1
for each 元组t2 in 关系r2
....
for each 元组tm in 关系rm
把t1,t2,...,tm连接成单个元组t
把t加入结果关系中
值得注意的是可能关系ri,rj中可能出现相同属性,所以我们在属性名前 加上关系名作为前缀 ,这样表示该属性来自哪个关系
用where子句来限制笛卡尔积建立的组合,使结果有意义
自然连接
natural join ,因为容易忘记where限制,如果没有where限制,以及投影的属性限制,那么出来的元组数会很多而且不知道哪个是哪个,所以用自然连接,因为 自然连接只考虑那些在两个关系中都出现的属性上取值相同的元组对。
1.只有两个关系做自然连接
2.如果有很多个关系 都用自然连接 结合在一起
select A1,A2,...,An
from r1 natural join r2 natural join ... natural join rm
where p;
3.如果 某些关系需要自然连接,某些关系笛卡尔积 ,可以如下:
4.只需要关系中的某个属性自然连接 :
为了避免关系中不止一个属性名相同,但是只需要某个属性连接,其他属性名内容可能互不相同,这样子会可能会造成不必要的错误。
指定需要哪个属性相等的自然连接
记得using后的属性要用括号括起来,不然报错
嵌套子查询
允许嵌套在where子句中,也允许嵌套在from语句中
子查询是嵌套在另一个查询中的select-from-where表达式。
where子句中子查询
用 in和 not in测试元组是否是集合中的成员,集合由select子句产生的一组值构成。
select xx from xxx where xxxx in(select-from-where)
select xx from xxx where xxxx not in(select-from-where)
嵌套子查询对集合进行比较
>some表示至少比某一个大
<some表示至少比某一个小
>all表示比全部都大
<all表示比全部都小
允许>=some,<=some,=some,<>some,<all,>all<=all,>=all,<>all
其中 =some 等价于 in , <>all 等价于 not in
验证如下:
为什么<>some不等于not in,因为<>some相当于选择该关系中全部属性值,因为它的中文含义是至少要大于some中一个或者至少小于some中一个。
而<>all表达的是大于全部且小于全部。
为什么=all在这种情况下一个都没有,因为=all相当于要选择出的属性值是等于这个集合中全部。
而=some的意思是集合中有一个属性值等于就行了所以就相当于in
判断嵌套子查询是否存在元组
exists 结构在作为参数的子查询非空时返回true值
not exists 相反
from子句中的子查询
返回的每一个都看成关系
可以用as给返回的关系重命名
操作即在from后加(select-from-where)即可
插入数据
按照建表的顺序以及声明的列的数据类型通过insert命令将数据加载到关系中, 插入的是元组
1.一次插入一条数据(属性值顺序和关系模式中属性排列顺序一致)
插入数据须知如果是字符类型,请注意的是用单引号括起来如 'dadasda' 如果在插入的数据是字符类型时,插入的字段有单引号那么注意用 两个单引号代替一个单引号。如 'I''m,A!'这样才能成功插入数据。
2.一次插入多条数据(属性值顺序和关系模式中属性排列顺序一致)
insert into xx values(),(),(),....,();
3.指定顺序插入属性值
4.将查询结果插入元组
insert into rr
select A1,A2,..,An
from r
where p;
更新数据
只修改更新部分属性的值,用update
update table_name set column_name=(操作)
1.给关系中某属性的所有值都修改
2.给关系中某属性的某些条件下的值修改
3.给不同情况修改不同内容
按常规做法可能就是写几个update语句,也是行的通的,但是代码量多。
也可用case如:
update xx set a=case
when 判断语句 then 操作
when 判断语句 then 操作
....
else 操作
end;
删除数据
删除请求和查询其实非常相似,但是它只能删除某个元组,不能只删除某个属性上的值
1.一般的语句如下:
delect from r
where P;
2.删除全部元组:
注意!它只是删除了全部元组没有删除表(关系)
只有drop table x,才会删除表
视图
出于安全考虑,给特定用户创建特定视图,不会修改到逻辑模型
定义视图
create view xx as <合法的查询表达式>;
SQL查询视图
和sql的表查询差不多
总结
提示:这里对文章进行总结:
以上就是今天要讲的内容,本文仅仅简单介绍了SQL语法,掌握SQL基础语法后可看sql高级特性。链接如下:SQL高级特性