版本:mysql5.7
MySQL中的数据类型
常用几个类型的介绍
创建与使用数据库
CREATE DATABASE 数据库名;
--创建数据库 ,指定字符集为utf8
CREATE DATABASE 数据库名 CHARACTER SET 'UTF8';
--判断数据库是否存在,如果存在就创建
CREATE DATABASE 数据库名 IF NOT EXISTS;
查看当前所有数据库
SHOW DATABASES;
查看当前正在使用的数据库
SELECT DATABASE(); --mysql的一个全局函数
查看指定库下所有表
SHOW TABLES FROM 数据库名
查看数据库的创建信息
SHOW CREATE DATABASE;
使用切换数据库
USE 数据库名
修改数据库
更高数据库字符集
ALTER DATABASE 数据库名 CHARACTER SET 字符集; #比如:gbk、utf8等
删除指定的数据库
DROP DATABASE 数据库名;
--先判断数据库是否存在,如果存在则删除指定数据库
DROP DATABASE IF EXISTS 数据库名;
创建表
--格式
CREATE TABLE [IF NOT EXISTS] 表名(
字段1, 数据类型 [约束条件] [默认值],
字段2, 数据类型 [约束条件] [默认值],
字段3, 数据类型 [约束条件] [默认值],
……
[表约束条件]
);
举例:
-- 创建表
CREATE TABLE emp (
-- int类型
emp_id INT,
-- 最多保存20个中英文字符
emp_name VARCHAR(20),
-- 总位数不超过15位
salary DOUBLE,
-- 日期类型
birthday DATE
);
--DESC 查看表结构
DESC emp
MySQL在执行建表语句时,将id字段的类型设置为int(11),这里的11实际上是int类型指定的显示宽度,默 认的显示宽度为11。也可以在创建数据表的时候指定数据的显示宽度。
CREATE TABLE dept(
-- int类型,AUTO_INCREMENT表示该字段自增
deptno INT(2) AUTO_INCREMENT,
dname VARCHAR(14),
loc VARCHAR(13),
-- 主键
PRIMARY KEY (deptno)
);
查看数据表结构
--显示表的结构
DESC 表名
--可以看到表创建时的详细语句
SHOW CREATE TABLE 表名
删除表
DROP TABLE IF EXISTS 表名
清空表
TRUNCATE TABLE detail_dept;
增删改
插入数据
按默认字段插入数据
INSERT INTO 表名
VALUES (value1,value2,....);
--VALUES可以写成VALUE,但是VALUES是标准写法
举例:
INSERT INTO departments
VALUES (70, 'Pub', 100, 1700);
INSERT INTO departments
VALUES (100, 'Finance', NULL, NULL);
指定字段插入
为表的指定字段插入数据,就是在INSERT语句中只向部分字段中插入值,而其他字段的值为表定义时的 默认值
举例:
INSERT INTO departments(department_id, department_name)
VALUES (80, 'IT');
同时插入多条记录
举例:
--用,分隔
INSERT INTO emp(emp_id,emp_name)
VALUES (1001,'shkstart'),
(1002,'atguigu'),
(1003,'Tom');
一个同时插入多行记录的INSERT语句等同于多个单行插入的INSERT语句,但是多行的INSERT语句 在处理过程中 效率更高
将查询结果插入到表中
举例:
INSERT INTO emp2
SELECT *
FROM employees
WHERE department_id = 90;
INSERT INTO sales_reps(id, name, salary, commission_pct)
SELECT employee_id, last_name, salary, commission_pct
FROM employees;
更新数据
使用 UPDATE 语句更新数据
UPDATE employees
SET department_id = 70
WHERE employee_id = 113;
--使用WHERE指定需要更新的数据
--如果没有WHERE,所有数据都将被更新
删除数据
--删除指定记录
DELETE FROM departments
WHERE department_name = 'Finance';
--如果没有WHERE,表中数据都将被删除
基本的增删改
使用SELECT
SELECT * FROM employees;
-- SELECT * 表示查询该表所有字段
SELECT last_name, department_id
FROM employees;
-- 指定查询要查找的字段
取别名
SELECT id AS "编号", `name` as "姓名" FROM t_stu; --起别名时,as都可以省略
-
重命名一个列 便于计算 紧跟列名
-
也可以在列名和别名之间加入关键字AS,别名使用双引号,以便在别名中包含空格或特 殊的字符并区分大小写
DISTINCT 去重
在SELECT语句中使用关键字DISTINCT去除重复行
SELECT DISTINCT department_id from employees;
DISTINCT 要放前面
SELECT DISTINCT department_id,salary FROM employees;
空值参与运算
所有运算符或列值遇到null值,运算结果都为null
这里要注意,在MySQL中,空值不等于空字符串。
SELECT查询常数
SELECT '我' AS 'a', last_name FROM employees;
显示表结构
使用DESCRIBE 或DESC
DESC employees;
过滤数据 WHERE
SELECT employee_id, last_name, job_id, department_id
FROM employees
WHERE department_id = 90 ;
WHRER子句紧随FROM子句
运算符
算术运算符 + - * / %
加法与减法
一个整数类型的值对整数进行加法和减法操作,结果还是一个整数;
一个整数类型的值对浮点数进行加法和减法操作,结果是一个浮点数;
在Java中,+的左右两边如果有字符串,那么表示字符串的拼接。
但是在MySQL中+只表示数 值相加。如果遇到非数值类型,先尝试转成数值,如果转失败,就按0计算。(补充:MySQL 中字符串拼接要使用字符串函数CONCAT()实现)
乘法与除法运算符
一个数乘以整数1和除以整数1后仍得原数;
一个数乘以浮点数1和除以浮点数1后变成浮点数,数值与原数相等;
一个数除以整数后,不管是否能除尽,结果都为一个浮点数;
一个数除以另一个数,除不尽时,结果为一个浮点数,并保留到小数点后4位;
在数学运算中,0不能用作除数,在MySQL中,一个数除以0为NULL。
比较运算符
比较结果为真返回1,为假返回0,其他情况返回null
等号运算符 =
-
如果等号两边的值、字符串或表达式都为字符串,则MySQL会按照字符串进行比较,其比较的 是每个字符串中字符的ANSI编码是否相等。
-
如果等号两边的值都是整数,则MySQL会按照整数来比较两个值的大小。
-
如果等号两边的值一个是整数,另一个是字符串,则MySQL会将字符串转化为数字进行比较。
-
如果等号两边的值、字符串或表达式中有一个为NULL,则比较结果为NULL。
SELECT 1 = 1, 'ABC' = 'ABC', '123' = 123 FROM dual;
安全等于 <=>
2.安全等于运算符 安全等于运算符()与等于运算符(=)的作用是相似的, 唯一的区别 是‘’可 以用来对NULL进行判断。在两个操作数均为NULL时,其返回值为1,而不为NULL;当一个操作数为NULL 时,其返回值为0,而不为NULL
用安全等于 NULL = NULL返回1,所以可以查到结果
不等于运算符 <> 或 !=
不等于运算符不能判断NULL值。如果两边的值有任意一个为NULL, 或两边都为NULL,则结果为NULL
非符号类型的运算符
空运算符 IS NULL 或ISNULL
判断一个值是否为NULL,如果为NULL则返回1,否则返回 0
最小值运算符 LEAST
SELECT LEAST (1,0,3),LEAST('S','A','B'),LEAST(1,NULL,2);
-
当参数是整数或者浮点数时,LEAST将返回其中最小的值
-
当参数为字符串时,返回字 母表中顺序最靠前的字符
-
当比较值列表中有NULL时,不能判断大小,返回值为NULL
最大值运算符GREATEST
SELECT GREATEST(1,0,2), GREATEST('b','a','c'), GREATEST(1,NULL,2);
BETWEEN AND 运算符
SELECT D FROM TABLE WHERE C BETWEEN A AND B,此时,当C大于或等于A,并且C小于或等于B时,结果为1,否则结果为0。
SELECT 1 BETWEEN 0 AND 1, 10 BETWEEN 11 AND 12, 'b' BETWEEN 'a' AND 'c';
IN运算符
IN运算符用于判断给定的值是否是IN列表中的一个值,如果是则返回1,否则返回0。如果给 定的值为NULL,或者IN列表中存在NULL,则结果为NULL
SELECT 'a' IN ('a','b','c'), 1 IN (2,3), NULL IN ('a','b'), 'a' IN ('a', NULL);
NOT IN运算符
NOT IN运算符用于于判断给定的值是否不是IN列表中的一个值,如果不是IN列表中的一 个值,则返回1,否则返回0。
LIKE运算符
LIKE运算符主要用来匹配字符串,通常用于模糊匹配,如果满足条件则返回1,否则返回 0。如果给定的值或者匹配条件为NULL,则返回结果为NULL
LIKE运算符通常使用如下通配符:
“%”:匹配0个或多个字符
“_”:只能匹配一个字符
--查找first_name 以S为开头的
SELECT first_name
FROM employees
WHERE first_name LIKE 'S%';
-- 查找第二个字母为o的
SELECT last_name
FROM employees
WHERE last_name LIKE '_o%';
四个字符,第二个字符为o
SELECT last_name FROM employees WHERE last_name LIKE '_o__';
ESCAPE
匹配% 和 _ 时,需要用 \ 进行转义
ESCAPE 可以指定一个字符替代“\”的作用
查询条件中所有通过ESCAPE指代的字符均会替代“\”的作用
REGEXP运算符
REGEXP运算符用来匹配字符串,语法格式为: expr REGEXP 匹配条件 。如果expr满足匹配条件,返回1
REGEXP运算符在进行匹配时,常用的有下面几种通配符:
-
‘^’匹配以该字符后面的字符开头的字符串。
-
‘$’匹配以该字符前面的字符结尾的字符串
-
)‘.’匹配任何一个单字符。
-
“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”或“b”或“c”。为了命名字符的范围,使用一 个‘-’。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。
-
‘*’匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的‘x’字符,“[0-9]*”匹配任何数量的数字, 而“*”匹配任何数量的任何字符。
SELECT 'shkstart' REGEXP '^s', 'shkstart' REGEXP 't$', 'shkstart' REGEXP 'hk';
SELECT 'aabcdec' REGEXP 'ab.de', 'acbde' REGEXP '[ab]';
逻辑运算符
1.逻辑非运算符 逻辑非(NOT或!)运算符表示当给定的值为0时返回1;当给定的值为非0值时返回0; 当给定的值为NULL时,返回NULL
2.逻辑与运算符 逻辑与(AND或&&)运算符是当给定的所有值均为非0值,并且都不为NULL时,返回 1;当给定的一个值或者多个值为0时则返回0;否则返回NULL。
3.逻辑或运算符 逻辑或(OR或||)运算符是当给定的值都不为NULL,并且任何一个值为非0值时,则返 回1,否则返回0;当一个值为NULL,并且另一个值为非0值时,返回1,否则返回NULL;当两个值都为 NULL时,返回NULL。
SELECT 1 OR -1, 1 OR 0, 1 OR NULL, 0 || NULL, NULL || NULL;
注:OR可以和AND一起使用,但是在使用时要注意两者的优先级,由于AND的优先级高于OR,因此先 对AND两边的操作数进行操作,再与OR中的操作数结合。
4.逻辑异或运算符 逻辑异或(XOR)运算符是当给定的值中任意一个值为NULL时,则返回NULL;如果 两个非NULL的值都是0或者都不等于0时,则返回0;如果一个值为0,另一个值不为0时,则返回1。
位运算符
位运算符是在二进制数上进行计算的运算符。位运算符会先将操作数变成二进制数,然后进行位运算, 最后将计算结果从二进制变回十进制数
运算符的优先级
数字编号越大,优先级越高,优先级高的运算符先进行计算
排序与分页
ORDER BY子句排序
-
ASC 升序
-
DESC 降序
-
ORDER BY子句在SELECT语句结尾
单列排列
SELECT last_name, job_id, department_id, hire_date FROM employees ORDER BY hire_date;
SELECT last_name, job_id, department_id, hire_date FROM employees ORDER BY hire_date DESC;
多列排序
SELECT last_name, department_id, salary
FROM employees
ORDER BY department_id, salary DESC;
先根排序的第一列(department_id)排序,若第一列的值相同,才会对第二列进行排序
分页 LIMIT
#显示前三条记录
SELECT * FROM employees LIMIT 0, 3
#显示前三条记录也可以这么写
SELECT * FROM employees LIMIT 3
#显示第11条到第20条的记录
#前面的数字表示从哪条记录开始查(索引从0开始)
#后面的数字表示显示的总的记录条数
SELECT * FROM employees LIMIT 10, 10;
#第21行到第30行的记录
SELECT * FROM employees LIMIT 20, 10;
多表查询
两个表通过department_id关联
SELECT last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;
在表中有相同列时,在列名之前加上表名前缀。
SELECT e.employee_id, e.last_name, e.department_id,
d.department_id, d.location_id
FROM employees e , departments d
WHERE e.department_id = d.department_id;
如果使用了表的别名,在查询字段中、过滤条件中就只能使用别名进行代替,不能使用原有的表名
非等值连接
SELECT e.last_name, e.salary, j.grade_level
FROM employees e,job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
自连接与非自连接
自连接
两张表是同一张表,只是用取别名的方式虚拟成两张表以代表不同的意义,然后
两个表再进行内连接,外连接等查询
SELECT CONCAT(worker.last_name ,' works for '
, manager.last_name)
FROM employees worker, employees manager
WHERE worker.manager_id = manager.employee_id ;
查询出last_name为'Chen'的员工的manager的信息
SELECT worker.last_name 'worker_name', manager.last_name 'manager_name'
FROM employees worker, employees manager
WHERE worker.manager_id = manager.employee_id AND worker.last_name = 'Chen';
内连接与外连接
除了查询满足条件的记录以外,外连接还可以查询某一方不满足条件的记录
-
内连接: 合并具有同一列的两个以上的表的行, 结果集 中不包含一个表与另一个表不匹配的行
-
外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的 行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。
-
如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表 。 如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表 。
JOIN ON
使用JOIN ON 创建连接
#将表1、2、3按照条件连接
SELECT table1.column, table2.column,table3.column
FROM table1
JOIN table2 ON(表1和表2的连接条件)
JOIN table3 ON(表2和表3的连接条件);
内连接(INNER JOIN)的实现
SELECT e.employee_id, e.last_name, e.department_id,
d.department_id, d.location_id
FROM employees e JOIN departments d
ON (e.department_id = d.department_id);
#后面可以加WHERE等子句
外连接(OUTER JOIN)的实现
>a 左外连接 LEFT OUTER JOIN
#语法
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 等其他子句;
举例:
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
LEFT OUTER JOIN departments d
ON (e.department_id = d.department_id);
右外连接(RIGHT OUTER JOIN)
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
RIGHT OUTER JOIN departments d
ON (e.department_id = d.department_id) ;
满外连接
可以通过LEFT JOIN UNION RIGHT JOIN实现
满外连接的结果 = 左右表匹配的数据 + 左表没有匹配到的数据 + 右表没有匹配到的数据
UNION合并查询结果
利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并 时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION ALL关键字分隔
#语法
SELECT column,... FROM table1
UNION [ALL]
SELECT column,... FROM table2
UNION操作符返回两个查询的结果集的并集,去除重复记录
UNION ALL 操作符返回两个查询的结果集的并集,不去重
注意:执行UNION ALL语句时所需要的资源比UNION语句少。如果明确知道合并数据后的结果数据 不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效率。
#查询中国用户中男性的信息以及美国用户中男性的用户信息
SELECT id,cname FROM t_chinamale WHERE csex='男'
UNION ALL
SELECT id,tname FROM t_usmale WHERE tGender='male';
7中SQL JOINS的实现
1.左外连接
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id;
2.右外连接
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id;
3. A - A∩B
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL;
4. B - A∩B
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL;
5. A∩B 内连接
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id;
6.满外连接
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
7. A∪B - A∩B
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;
USING 连接
当我们进行连接的时候,SQL99还支持使用 USING 指定数据表里的 同名字段 进行等值连接。但是只能配合JOIN一起使用
SELECT employee_id, last_name, department_name
FROM employees e JOIN departments d
USING (department_id);
#关联名称要一致
单行函数
略
聚合函数
聚合函数作用于一组数据,并对一组数据返回一个值
-
AVG()
-
SUM()
-
MAX()
-
MIN()
-
COUNT()
AVG和SUM函数
可以对数值型数据使用AVG和SUM函数
SELECT AVG(salary), MAX(salary), MIN(salary), SUM(salary)
FROM employees;
MIN和MAX函数
可以对任意数据类型的数据使用MIN和MAX函数
SELECT MIN(hire_date), MAX(hire_date)
FROM employees;
COUNT函数
记录表中记录总数,适用于任意数据类型
SELECT COUNT(*)
FROM employees
WHERE department_id = 50;
--也可以放常量
SELECT COUNT(1)
FROM employees
WHERE department_id = 50;
#COUNT(expr) 返回expr不为空的记录总数
SELECT COUNT(commission_pct)
FROM employees
GROUP BY
可以使用GROUP BY子句将表中的数据分成若干组
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id ;
-
在SELECT列表中所有未包含在组函数中的列都应该包含在 GROUP BY子句中
-
包含在 GROUP BY 子句中的列不必包含在SELECT 列表中
--可以使用多个列分组
SELECT department_id dept_id, job_id, SUM(salary)
FROM employees
GROUP BY department_id, job_id ;
GROUP BY中使用WITTH ROLLUP
使用 WITH ROLLUP ,此函数是对聚合函数进行求和,注意 with rollup是对 group by 后的第一个字段,进行分组求和。
SELECT department_id,AVG(salary)
FROM employees
WHERE department_id > 80
GROUP BY department_id WITH ROLLUP;
当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是互相排斥的。
HAVING(过滤分组)
-
行已经被分组
-
使用了聚合函数
-
满足HAVING 子句中条件的分组将被显示
-
HAVING 不能单独使用,必须要跟 GROUP BY 一起使用
SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000 ;
WHERE和HAVING的对比
-
WHERE 可以直接使用表中的字段作为筛选条件,但不能使用分组中的计算函数作为筛选条件;
-
HAVING 必须要与 GROUP BY 配合使用,可以把分组计算的函数和分组字段作为筛选条件
-
如果需要通过连接从关联表中获取需要的数据,WHERE 是先筛选后连接,而 HAVING 是先连接后筛选(WHERE更高效)
查询的结构
#方式1:
SELECT ...,....,...
FROM ...,...,....
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
#方式2:
SELECT ...,....,...
FROM ... JOIN ...
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
关键字顺序不能颠倒
SELECT语句执行顺序
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT 的字段 -> DISTINCT
-> ORDER BY -> LIMIT
子查询
子查询指一个查询语句嵌套在另一个查询语句内部的查询
很多时候查询需要从结果集中获取数据,或者需要从同一个表中先计算得出一个数据结果,然后与这个数据结果进行比较
SELECT last_name,salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
SELECT last_name, job_id, salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 141
)
AND salary > (
SELECT salary
FROM employees
WHERE employee_id = 143
);
字段可以成对比较
SELECT employee_id, manager_id, department_id
FROM employees
WHERE (manager_id, department_id) IN
(SELECT manager_id, department_id
FROM employees
WHERE employee_id IN (141, 174))
AND employee_id NOT IN (141, 174);
HAVING 中的子查询(先执行子查询)
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) >
(SELECT MIN(salary)
FROM employees
WHERE department_id = 50);
多行子查询
返回其他job_id中比job_id为'IT_PROG'部门任意工资低的员工的员工号,姓名,job_id,salary
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary < ANY
(SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';
查询平均工资最低的部门
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) <= ALL(
SELECT AVG(salary)
FROM employees
GROUP BY department_id
);
相关子查询
如果子查询的执行依赖于外部查询,通常情况下是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为 关联子查询 。
查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
SELECT last_name, salary, department_id
FROM employees e1
WHERE e1.salary >
(SELECT AVG(salary)
FROM employees
WHERE department_id = e1.department_id
);
在FROM中使用子查询
SELECT last_name, salary, e1.department_id
FROM employees e1,(SELECT department_id, AVG(salary) avg_salary FROM employees
GROUP BY department_id) e2
WHERE e1.department_id = e2.department_id
AND e2.avg_salary < e1.salary
from型的子查询:子查询是作为from的一部分,子查询要用()引起来,并且要给这个子查询取别 名, 把它当成一张“临时的虚拟的表”来使用。
EXISTS 与 NOT EXISTS关键字
SELECT employee_id, last_name, job_id, department_id
FROM employees e1
WHERE EXISTS ( SELECT *
FROM employees e2
WHERE e2.manager_id =
e1.employee_id);
相关更新
UPDATE table1 alias1
SET column = (SELECT expression
FROM table2 alias2
WHERE alias1.column = alias2.column);
依据一个表的数据去更新另一个表的数据
UPDATE employees e
SET department_name = (SELECT department_name
FROM departments d
WHERE e.department_id = d.department_id);
相关删除
DELETE FROM table1 alias1
WHERE column operator (SELECT expression
FROM table2 alias2
WHERE alias1.column = alias2.column);
依据一个表的数据删除另一个表的数据
DELETE FROM employees e
WHERE employee_id in
(SELECT employee_id
FROM emp_history
WHERE employee_id = e.employee_id);
在许多 DBMS 的处理过 程中,对于自连接的处理速度要比子查询快得多,一般建议使用自连接