SQL
基础
数据库
数据库是一个保存有组织数据的容器
数据库软件应该称为数据库管理系统(DBMS),数据库是通过DBMS创建和操纵的容器
表
表是一种结构化的文件,可用来存储某种特定类型的数据。描述表的这组信息就是所谓的模式,模式可以用来描述数据库中特定的表,也可以用来描述整个数据库(和其中表的关系)
主键
一列(或一组列),其值能够唯一标识表中的每一行
主键中的值不允许修改和更新,主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)
检索数据
检索不同的值
DISTINCT关键字,指示数据库只返回不同的值
不能部分使用DISTINCT,DISTINCT关键字作用于所有列出来的列,除非指定的几列的行值完全相同,不然所有的不重复的行都会被检索出来。
限制结果
如果查询结果只想返回特定数量的行,是可行的。但是在各种数据库种的SQL语句实现并不相同。
在MySQL、MariaDB、PostgreSQL或者SQLite种,需要使用LIMIT子句
下列代码返回不超过5行的数据
SELECT prod_name
FROM Products
LIMIT 5;
返回第5行起的5行数据 第一个数字是指从哪开始,第二个数字是检索的行数
SELECT prod_name
FROM Products
LIMIT 5 OFFSET 5;
注释
– 后面的文本为注释 多行注释与java一样
排序检索数据
排序数据
如果不排序的话,数据一般将以它在底层表中出现的顺序显示,这有可能是数据最初添加到表中的顺序。但是如果数据随后进行过更新或删除,那么这个顺序将会受到DBMS重用回收存储空间的方式的影响,因此如果不明确规定排序顺序,则不应该假定检索的数据的顺序有任何意义。
SQL子句:SQL语句由子句构成,有些子句是必需的,有些是可选的。
以字母顺序排序,在指定一条ORDER BY 子句时,应保证它是SELECT语句的最后一条子句,如果它不是最后的子句,将会出现错误消息
SELECT prod_name
FROM Products
ORDER BY prod_name;
按多个列排序
如果要按多个列进行排序,简单指明列名,列名之间用逗号分开即可
SELECT prod_id,prod_price,prod_name
FROM Products
ORDER BY prod_price, prod_name;
对于上述例子中的输出,仅在多个行具有相同的prod_price值时才对产品按prod_name进行排序。如果prod_price列中所有的值都是唯一的,则不会按prod_name排序
按列位置排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;
输出与上面的查询相同,ORDER BY 标识按SELECT清单中的第二个列进行排序。缺点是在对SELECT清单进行更改时容易错误地对数据进行排序(忘记对ORDER BY 子句做对应的改动),如果排序的列不再SELECT 清单中,显然不能使用这个技术
指定排序方向
使用降序排序必须使用DESC关键字
过滤数据
使用WHERE子句
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ry3wNZLf-1631967387499)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210915202735044.png)]
高级数据过滤
IN操作符
IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配,IN取一组由逗号分隔,括在圆括号中的合法值
SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN ('DLL01','BRSU1')
ORDER BY prod_name;
此SELECT语句检索由供应商DLL01和BRSU1制造的所有产品。IN操作符后跟由逗号分割的合法值,这些值必须括在圆括号中。
IN操作符的优点:
- 在有很多合法选项时,IN操作符的语法更清楚、更直观
- 在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理
- IN操作符一般比一组OR操作符执行得更快
- IN的最大优点是可以包含其他SELECT语句,能够更动态地建立WHERE子句
NOT操作符
WHERE子句中的NOT操作符有且仅有一个功能,就是否定其后所跟的任何条件。因为NOT从不单独使用,NOT关键字可以用在要过滤的列前,而不仅是在其后
SELECT prod_name
FROM Products
WHERE NOT vend_id = 'DLL01'
ORDER BY prod_name;
用通配符进行过滤
LIKE操作符
为在搜索子句中使用通配符,必须使用LIKE操作符。LIKE指示DBMS,后跟的搜索模式利用通配符匹配而不是简单的相等匹配进行比较。
%通配符
%表示任何字符出现任意次数,代表搜索模式中给定位置的0个、1个或多个字符,除了NULL
_通配符
只匹配单个字符
[]通配符
方括号用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符
与前面描述的通配符不一样,并不是所有的DBMS都支持用来创建集合的[]。只有微软的Access和SQL Server 支持集合
找出所有名字以J或M起头的联系人:
SELECT cust_contact
FROM Customers
WHERE cust_contact LIKE '[JM]%'
ORDER BY cust_contact;
此通配符可以用前缀字符^来否定
如果使用的是Microsoft Access 需要用!而不是^来否定一个集合
创建计算字段
计算字段
计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句内创建的。
拼接字段
SELECT Concat(vend_name), ' (', vend_contry, ')')
FROM Vendors
ORDER BY vend_name;
上列的SELECT语句拼接一下元素:
存储在vend_name列的名字
包含一个空格和一个左圆括号的字符串
存储在vend_country列中的国家
包含一个右圆括号的字符串
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fp8FeWHX-1631967387502)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210915214859662.png)]
使用别名
用AS关键字赋予,可以命名计算字段
执行算术计算
计算字段的另一常见用途是对检索出的数据进行算数计算
使用函数处理数据
每一个DBMS都有特定函数,事实上,只有少数几个函数被所有主要的DBMS等同地支持。虽然所有类型的函数一般都可以在每个DBMS中使用,但各个函数的名称和语法可能极其不同。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a9gejce5-1631967387504)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210916201057770.png)]
汇总数据
聚集函数
对某些行运行的函数,计算并返回一个值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-63ikXxIp-1631967387508)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210916201807112.png)]
聚集不同值
使用DISTINCT关键字,但是DISTINCT不能用于COUNT(*)
分组数据
GROUP BY 子句
- GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前
- 除聚集函数以外,SELECT语句中的每一行都必须在GROUP BY子句中给出
- GROUP BY子句可以包含任意数量的列,因此可以对分组进行嵌套
- 如果在GROUP BY子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算
过滤分组
HAVING 需要结合GROUP BY子句使用,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
分组和排序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ELBOXog-1631967387510)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210916203403663.png)]
SELECT子句顺序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dP4AxHQY-1631967387511)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210916203602660.png)]
使用子查询
子查询
作为子查询的SELECT语句只能查询单个列,企图检索多个列将返回错误
联结表
联结
创建联结
完全限制列名:在引用的列可能出现歧义时,必须使用完全限制列名(用一个句点分割表名和列名)。如果引用一个没有用表名限制的具有歧义的列名,大多数DBMS会返回错误
要保证所有的联结都有WHERE子句,否则DBMS将返回笛卡尔积表
内联结
SELECT vend_name, prod_name; prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;
自联结
SELECT c1.cust_id,c1.cust_name, c1_cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones';
许多的DBMS处理联结远比处理子查询快得多
自然联结
自然联结排除多次出现,使每列都只返回一次
外联结
SELECT Customers.cust_id,Order.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id;
在使用OUTER JOIN语法时,必须使用RIGHT 或 LEFT 关键字指定包括其所有行的表(RIGHT指出的是 OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)
全外联结,检索两个表中的所有行并且关联那些可以关联的行
组合查询
主要有两种情况需要使用组合查询
-
在一个查询中从不同的表返回结构数据 -
对一个表执行多个查询,按一个查询返回数据
UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分割
UNION中每个查询必须包含相同的列、表达式或聚集函数(不过,各个列不需要以相同的次序列出)
列数据类型必须兼容:类型不必完全相同,但是必须是DBMS可以隐含转换的类型
包含或取消重复的行
如果想返回所有匹配行使用UNION ALL,默认UNION 不返回重复行
对组合查询的结构排序
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All'
ORDER BY cust_name, cust_contact;
最后的ORDER BY看似是最后一条SELECT语句的组成部分,实际上DBMS用它来排序所有的SELECT语句返回的所有结果
插入
从一个表复制到另一个表
使用SELECT INTO 语句
更新与删除
UPDATE Customers
SET cust_email = 'kim@thetoystore.com'
WHERE cust_id = '1000000005';
UPDATE语句总是要以要更新的表名开始,SET命令用来将新值赋给被更新的列。
删除
DELETE不需要列名或通配符,DELETE删除整行而不是删除列,要删除指定的列,使用UPDATE语句
如果执行DELETE语句而不带WHERE子句,表的所有数据都将被删除
表
创建表
CREATE TABLE Products
(
prod_id CHAR(10) NOT NULL,
vend_id CHAR(10) NOT NULL,
prod_name CHAR(254) NOT NULL,
prod_price DECIMAL(8,2) NOT NULL,
prod_desc VARCHAR(1000) NULL
);
对于Mysql而言varchar必须替换为text
使用NULL值
每个表列要么是NULL列,要么是NOT NULL列
指定默认值
SQL允许指定默认值,在插入行时如果不给出值,DBMS将自动采用默认值。默认值在CREATE TABLE语句的列定义中用关键字DEFAULT指定
更新表
ALTER TABLE 可以更改或删除列、增加约束或增加键
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DaVnmxjf-1631967387512)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210916215332056.png)]
删除表
DROP TABLE
视图
视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询
视图的常见应用:
- 重用SQL语句
- 简化复杂的SQL操作
- 使用表的一部分而不是整个表
- 保护数据
- 更改数据格式和表示
规则
视图必须唯一命名
对于可以创建的视图数目没有限制
创建视图,必须具有足够的访问权限
许多DBMS禁止在视图查询中使用ORDER BYT子句
视图不能索引,也不能有关联的触发器或默认值
有些DBMS把视图作为只读的查询
创建视图
CREATE VIEW
存储过程
存储过程就说为以后使用而保存的一条或多条SQL语句,可将其视为批文件,虽然它们的作用不仅限于批处理。MySQL 5已经支持存储过程
执行存储过程
EXECUTE 接受存储过程名和需要传递给它的参数
EXECUTE AddNewProduct( 'JTS01',
'Stuffed Eiffel Tower',
6.49,
'Plush stuffed toy with the text La
?Tour Eiffel in red white and blue' );
管理事务处理
事务处理
使用事务处理,通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性
事务:一组SQL语句
回退:撤销指定的SQL语句的过程
提交:将未存储的SQL语句结果写入数据库表
保留点:事务处理中设置的临时占位符,可以对它发布回退
使用游标
游标是一个存储在DBMS服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。
约束
外键
外键是表中的一列,其值必须列在另一表的主键中,外键是保证引用完整性的极其重要部分。
唯一约束
唯一约束既可以用UNIQUE关键字在表定义中定义,也可以用单独的CONSTRAINT定义
检查约束
CHECK(条件)可以保证插入或更新的行都会被检查满足这个条件与否
索引
a ?Tour Eiffel in red white and blue’ );
## 管理事务处理
### 事务处理
使用事务处理,通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性
事务:一组SQL语句
回退:撤销指定的SQL语句的过程
提交:将未存储的SQL语句结果写入数据库表
保留点:事务处理中设置的临时占位符,可以对它发布回退
## 使用游标
游标是一个存储在DBMS服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。
## 约束
### 外键
外键是表中的一列,其值必须列在另一表的主键中,外键是保证引用完整性的极其重要部分。
### 唯一约束
唯一约束既可以用UNIQUE关键字在表定义中定义,也可以用单独的CONSTRAINT定义
### 检查约束
CHECK(条件)可以保证插入或更新的行都会被检查满足这个条件与否
### 索引
|