SQL基础
1. 创建数据库表
创建数据表(Table)之前需要先创建数据库(Database),或者必许在已存在的数据库上创建数据表。
数据库创建语句
CREATE DATABASE 数据库名1CREATE DATABASE shop;数据表创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17CREATE TABLE <表名> ( <列名1> <数据类型> <该列所需约束>, ...... <该表的约束1>, <该表的约束2>, ..... ); CREATE TABLE Product ( product_id CHAR(4) NOT NULL, // 商品编号 product_name VARCHAR(100) NOT NULL, // 商品名称 product_type VARCHAR(32) NOT NULL, // 商品种类 sale_price INTEGER, // 销售单价 purchase_price INTEGER, // 进货单价 regist_date DATE, // 登记日期 PRIMARY KEY (product_id)); )表的删除和更新
表的删除
1DROP TABLE 表名;表定义的更新(
ALTER TABLE)添加列
1ALTER TABLE <表名> ADD COLUMN <列的定义>;删除列
1ALTER TABLE <表名> DROP COLUMN <列名>;向表中插入数据
1 2 3 4 5 6 7 8 9 10 11 12INSERT INTO <表名> VALUES('VALUE1','VALUE2',...); START TRANSACTION; INSERT INTO Product VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20'); INSERT INTO Product VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11'); INSERT INTO Product VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL); INSERT INTO Product VALUES ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20'); INSERT INTO Product VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15'); INSERT INTO Product VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20'); INSERT INTO Product VALUES ('0007', '擦菜板', '厨房用具', 880, 790, '2008-04-28'); INSERT INTO Product VALUES ('0008', '圆珠笔', '办公用品', 100, NULL,'2009-11-11'); COMMIT;
表的修改
变更表名
1RENAME TABLE <原表名> TO <新表名>;
2. 查询基础
2.1 SELECT语句基础
列的查询
| |
查询出表中所有的列
| |
为列设定别名
别名可以使用中文,需要双引号括起来("")
| |
常数的查询
| |
从结果中删除重复行
在使用 DISTINCT 时,NULL 也被视为一类数据。NULL 存在于多行中时,也会被合并为一条 NULL 数据。
| |
条件查询(WHERE)
WHERE字句要紧跟在FROM字句之后。
| |
注释
- 单行注释,
-- - 多行注释,
/*和*/之间
2.2 算术运算符和比较运算符
算术运算符
1 2 3SELECT product_name, sale_price, sale_price * 2 AS "sale_price_x2" FROM Product;四则运算:
含义 运算符 加法运算 + 减法运算 - 乘法运算 * 除法运算 / SELECT子句中可以使用常数或者表达式。所有包含 NULL 的计算,结果肯定是 NULL。
比较运算符
1 2 3SELECT product_name, product_type FROM Product WHERE sale_price <> 500;运算符 含义 = 和~相等 <> 和~不相等 >= 大于等于~ > 大于~ <= 小于等于~ < 小于~ 1 2 3 4 5 6 7 8 9 10 11SELECT product_name, product_type, sale_price FROM Product WHERE sale_price >= 1000; SELECT product_name, product_type, regist_date FROM Product WHERE regist_date < '2009-09-27'; SELECT product_name, sale_price, purchase_price FROM Product WHERE sale_price - purchase_price >= 500;注意:一定要让不等号在左,等号在右。
字符串类型的数据原则上按照字典顺序进行排序,不能与数字的大小顺序混淆。
不能对NULL使用比较运算符:SQL 提供了专门用来判断是否为 NULL 的
IS (NOT) NULL运算符。
2.3 逻辑运算符
NOT运算符NOT 不能单独使用,必须和其他查询条件组合起来使用。
1 2 3SELECT product_name, product_type, sale_price FROM Product WHERE NOT sale_price >= 1000;NOT运算符用来否定某一条件,但是不能滥用。
AND运算符和OR运算符在 WHERE 子句中使用
AND运算符或者OR运算符,可以对多个查询条件进行组合。AND运算符在其两侧的查询条件都成立时整个查询条件才成立,其意思相当于“并且”。OR运算符在其两侧的查询条件有一个成立时整个查询条件都成立,其意思相当于“或者”。1 2 3 4SELECT product_name, purchase_price FROM Product WHERE product_type = '厨房用具' AND sale_price >= 3000;
多个查询条件进行组合时,需要使用AND运算符或者OR运算符。
通过括号强化处理
AND运算符优先于OR运算符。1 2 3 4 5SELECT product_name, product_type, regist_date FROM Product WHERE product_type = '办公用品' AND ( regist_date = '2009-09-11' OR regist_date = '2009-09-20');逻辑运算符和真值
NOT、AND 和 OR 称为逻辑运算符。真值就是TRUE或者FALSE。
使用 AND 运算符进行的逻辑运算称为逻辑积,使用 OR 运算符进行的逻辑运算称为逻辑和。
3. 聚合与排序
3.1 对表进行聚合查询
聚合函数
常用函数:
| 函数名 | 作用 |
|---|---|
| COUNT | 计 算 表 中 的 记 录 数( 行 数 ) |
| SUM | 计算表中数值列中数据的合计值 |
| AVG | 计算表中数值列中数据的平均值 |
| MAX | 求出表中任意列中数据的最大值 |
| MIN | 求出表中任意列中数据的最小值 |
用于汇总的函数称为聚合函数或者聚集函数。
| |
计算NULL之外的数据的行数
| |
对于 COUNT 函数来说,参数列不同计算的结果也会发生变化。
COUNT函数的结果根据参数的不同而不同。COUNT(*)会得到包含NULL的数据行数,而COUNT(<列名>)会得到NULL之外的数据行数。
计算合计值
使用SUM()函数。
| |
所有的聚合函数,如果以列名为参数,那么在计算之前就已经把NULL 排除在外了。因此,无论有多少个 NULL 都会被无视。
计算平均值
使用AVG ()函数,语法与SUM()函数相同
| |
计算最大值和最小值
最大值使用MAX()函数,最小值使用MIN()函数。
| |
使用聚合函数删除重复值(关键字DISTINCT)
| |
想要计算值的种类时,可以在COUNT函数的参数中使用DISTINCT。
不仅限于 COUNT 函数,所有的聚合函数都可以使用 DISTINCT。
在聚合函数的参数中使用DISTINCT,可以删除重复数据。
3.2 对表进行分组
GROUP BY子句
使用聚合函数和GROUP BY子句时需要注意以下 4点:
- 只能写在
SELECT子句之中 GROUP BY子句中不能使用SELECT子句中列的别名GROUP BY子句的聚合结果是无序的WHERE子句中不能使用聚合函数
| |
在 GROUP BY 子句中指定的列称为聚合键或者分组列。GROUP BY 子句也和 SELECT 子句一样,可以通过逗号分隔指定多列。
GROUP BY 子句的书写位置也有严格要求,一定要写在FROM 语句之后(如果有 WHERE 子句的话需要写在 WHERE 子 句 之 后 )。
聚合键中包含NULL的情况
当聚合键中包含 NULL 时,也会将NULL 作为一组特定的数据。聚合键中包含NULL时,在结果中会以“不确定”行(空行)的形式表现出来。
使用WHERE子句时GROUP BY的执行结果
| |
像这样使用 WHERE 子句进行汇总处理时,会先根据 WHERE 子句指定的条件进行过滤,然后再进行汇总处理。
| |
GROUP BY 和 WHERE 并用时 SELECT 语句的执行顺序:
| |
与聚合函数和GROUP BY子句有关的常见错误
在
SELECT子句中书写了多余的列在使用
COUNT这样的聚合函数时,SELECT子句中的元素有严格的限制。实际上,使用聚合函数时,SELECT子句中只能存在以下三种元素。- 常数
- 聚合函数
GROUP BY子句中指定的列名(也就是聚合键)
使用
GROUP BY子句时,SELECT子句中不能出现聚合键之外的列名。在
GROUP BY子句中写了列的别名在
GROUP BY子句中是不能使用别名的。GROUP BY子句的结果能排序吗不能排序,结果是随机的。
在
WHERE子句中使用聚合函数只有
SELECT子句和HAVING子句(以及ORDER BY子句)中能够使用聚合函数。
3.3 为聚合结果指定条件
HAVING子句
对集合指定条件就需要使用HAVING 子句,HAVING 子句必须写在 GROUP BY 子句之后
| |
使用HAVING子句时SELECT语句的顺序。
| |
| |
HAVING子句的构成要素
HAVING 子句中能够使用的 3 种要素:
- 常数
- 聚合函数
GROUP BY子句中指定的列名(即聚合键)
HAVING 子句是用来指定“组”的条件的。因此,“行”所对应的条件还是应该写在 WHERE 子句当中。
WHERE 子句 = 指定行所对应的条件HAVING 子句 = 指定组所对应的条件
聚合键所对应的条件不应该书写在HAVING子句当中,而应该书写在WHERE子句当中。
3.4 对查询结果进行排序
ORDER BY子句
| |
子句的书写顺序:
| |
指定升序或降序
ASC 和 DESC 是 ascendent(上升的)和descendent(下降的)这两个单词的缩写。
| |
未指定ORDER BY子句中排列顺序时会默认使用升序进行排列。
NULL的顺序
使用含有 NULL 的列作为排序键时,NULL 会在结果的开头或末尾汇总显示。
在排序键中使用显示用的别名
在 GROUP BY 子句中不能使用SELECT 子句中定义的别名,但是在 ORDER BY 子句中却是允许使用别名的。
| |
使用 HAVING 子句时 SELECT 语句的顺序:
| |
SELECT 子句的执行顺序在 GROUP BY 子句之后,ORDER BY 子句之前。
ORDER BY子句中可以使用的列
ORDER BY 子句中也可以使用存在于表中、但并不包含在 SELECT子句之中的列
| |
在ORDER BY子句中可以使用SELECT子句中未使用的列和聚合函数。
不要使用列编号
4. 数据更新
4.1 数据的插入(INSERT语句的使用方法)
INSERT语句
| |
| |
多行INSERT
| |
列清单的省略
| |
插入NULL
INSERT 语句中想给某一列赋予 NULL 值时,可以直接在 VALUES子句的值清单中写入 NULL。
要插入 NULL 的列一定不能设置 NOT NULL 约束。向设置了 NOT NULL 约束的列中插入 NULL 时,INSERT 语句会出错,导致数据插入失败。
插入默认值
通过显式方法插入默认值
在
VALUES子句中指定DEFAULT关键字1INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ('0007', '擦菜板', '厨房用具', DEFAULT, 790, '2009-04-28');通过隐式方法插入默认值
插入默认值时也可以不使用
DEFAULT关键字,只要在列清单和VALUES中省略设定了默认值的列就可以了。通过隐式方法设定默认值
1INSERT INTO Product (product_id, product_name, product_type, purchase_price, regist_date) VALUES ('0007', '擦菜板', '厨房用具', 790, '2009-04-28'); // 省略了sale_price列及对应的值未设定默认值的情况
1 2 3 4-- 省略purchase_price列(无约束):会赋予“NULL” INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, regist_date) VALUES ('0008', '圆珠笔', '办公用品', 100, '2009-11-11'); -- 省略product_name列(设置了NOT NULL约 束 ):错 误 ! INSERT INTO ProductIns (product_id, product_type, sale_price, purchase_price, regist_date) VALUES ('0009', '办公用品', 1000, 500, '2009-12-12');省略
INSERT语句中的列名,就会自动设定为该列的默认值(没有默认值时会设定为NULL)。
从其他表中复制数据
创建ProductCopy表(表结构与Product完全一致,只是表名不一样而已):
1 2 3 4 5 6 7 8 9 10CREATE TABLE ProductCopy ( product_id CHAR(4) NOT NULL, product_name VARCHAR(100) NOT NULL, product_type VARCHAR(32) NOT NULL, sale_price INTEGER, purchase_price INTEGER, regist_date DATE, PRIMARY KEY (product_id) );INSERT … SELECT语句
1 2-- 将商品表中的数据复制到商品复制表中 INSERT INTO ProductCopy (product_id, product_name, product_type, sale_price, purchase_price, regist_date) SELECT product_id, product_name, product_type, sale_price, purchase_price, regist_date FROM Product;多种多样的SELECT语句
ProductType表:
1 2 3 4 5 6 7 8 9 10 11 12CREATE TABLE ProductType ( product_type VARCHAR(32) NOT NULL, sum_sale_price INTEGER, sum_purchase_price INTEGER, PRIMARY KEY (product_type) ); INSERT INTO ProductType (product_type, sum_sale_price, sum_purchase_price) SELECT product_type, SUM(sale_price), SUM(purchase_price) FROM Product GROUP BY product_type;4.2 数据的删除(DELETE语句的使用方法)
DROP TABLE语句和DELETE语句
DROP TABLE语句可以将表完全删除DELETE语句会留下表(容器),而删除表中的全部数据
DELETE语句的基本语法
1DELETE FROM <表名>;DELETE语句的删除对象并不是表或者列,而是记录(行)。
指定删除对象的DELETE语句(搜索型DELETE)
1DELETE FROM <表名> WHERE <条件>;可以通过WHERE子句指定对象条件来删除部分数据。与
SELECT语句不同的是,DELETE语句中不能使用GROUP BY、HAVING和ORDER BY三类子句,而只能使用WHERE子 句 。删除和舍弃
只能删除表中全部数据的TRUNCATE语句
1TRUNCATE <表名>;与
DELETE不同的是,TRUNCATE只能删除表中的全部数据,而不能通过WHERE子句指定条件来删除部分数据。也正是因为它不能具体地控制删除对象,
所以其处理速度比DELETE要快得多。
4.3 数据的更新(UPDATE语句的使用方法)
UPDATE语句的基本语法
1 2UPDATE <表名> SET <列名> = <表达式>;指定条件的UPDATE语句(搜索型UPDATE)
1 2 3UPDATE <表名> SET <列名> = <表达式> WHERE <条件>;使用NULL进行更新
使用
UPDATE也可以将列更新为NULL(该更新俗称为NULL清空)。1 2 3UPDATE Product SET regist_date = NULL WHERE product_id = '0008';使用UPDATE语句可以将值清空为NULL(但只限于未设置NOT NULL约束的列)。
多列更新
使用逗号对列进行分隔排列
1 2 3 4UPDATE Product SET sale_price = sale_price * 10, purchase_price = purchase_price / 2 WHERE product_type = '厨房用具';将列用()括起来的清单形式
1 2 3UPDATE Product SET (sale_price, purchase_price) = (sale_price * 10, purchase_price / 2) WHERE product_type = '厨房用具';
4.4 事务
什么是事务
事务就是需要在同一个处理单元中执行的一系列更新处理的集合 。
创建事务
1 2 3 4 5 6事务开始语句; DML语句①; DML语句②; DML语句③; ...... 事务结束语句(COMMIT或者ROLLBACK);使用事务开始语句和事务结束语句,将一系列 DML 语句(
INSERT/UPDATE/DELETE语句)括起来,就实现了一个事务处理。各个DBMS的事务开始语句:
SQL Server、PostgreSQL
1BEGIN TRANSACTIONMySQL
1START TRANSACTIONOracle、DB2
无
更新商品信息的事务
1 2 3 4 5 6 7 8 9 10START TRANSACTION; -- 将运动T恤的销售单价降低1000日元 UPDATE Product SET sale_price = sale_price - 1000 WHERE product_name = '运动T恤'; -- 将T恤衫的销售单价上浮1000日元 UPDATE Product SET sale_price = sale_price + 1000 WHERE product_name = 'T恤衫'; COMMIT;COMMIT——提交处理
COMMIT是提交事务包含的全部更新处理的结束指令,相当于文件处理中的覆盖保存。一旦提交,就无法恢复到事务开始前的状态了。COMMIT的流程 =直线进行
11.事务开始语句 ------> 2.执行更新语句(DML) ------> 3.执行COMMIT结束后的状态:②中的所有更新都被反映到了数据库中
虽然我们可以不清楚事务开始的时间点,但是在事务结束时一定要仔细进行确认。
ROLLBACK——取消处理
ROLLBACK是取消事务包含的全部更新处理的结束指令,相当于文件处理中的放弃保存。一旦回滚,数据库就会恢复到事务开始之前的状态。ROLLBACK的流程 =掉头回到起点
11.事务开始语句 ------> 2.执行更新语句(DML) ------> 3.执行ROLLBACK结束后的状态:和①执行前相同
1 2 3 4 5 6 7 8 9 10START TRANSACTION; -- 将运动T恤的销售单价降低1000日元 UPDATE Product SET sale_price = sale_price - 1000 WHERE product_name = '运动T恤'; -- 将T恤衫的销售单价上浮1000日元 UPDATE Product SET sale_price = sale_price + 1000 WHERE product_name = 'T恤衫'; ROLLBACK;事务处理何时开始
实际上,几乎所有的数据库产品的事务都无需开始指令。这是因为大部分情况下,事务在数据库连接建立时就已经悄悄开始了,并不需要用户再明确发出开始指令。
事务类别:
- 每条 SQL语句就是一个事务(自动提交模式)
- 直到用户执行COMMIT或者ROLLBACK为止算作一个事务
默认使用自动提交模式的
DBMS有SQL Server、PostgreSQL和MySQL等
ACID特性
DBMS 的事务都遵循四种特性,将这四种特性的首字母结合起来统称为 ACID 特性。这是所有 DBMS 都必须遵守的规则。
原子性(Atomicity)
原子性是指在事务结束时,其中所包含的更新处理要么全部执行,要么完全不执行,也就是要么占有一切要么一无所有。
一致性(Consistency)
一致性指的是事务中包含的处理要满足数据库提前设置的约束,如主键约束或者
NOT NULL约束等。隔离性(Isolation)
隔离性指的是保证不同事务之间互不干扰的特性。
持久性(Durability)
持久性也可以称为耐久性,指的是在事务(不论是提交还是回滚)结束后,
DBMS能够保证该时间点的数据状态会被保存的特性。即使由于系统故障导致数据丢失,数据库也一定能通过某种手段进行恢复。
复杂查询
视图
视图和表
支付宝
微信