开启关闭连接
开启关闭:
第一种方法:电脑里面搜服务,服务里面找到MySQL,右键可以开启关闭
第二种方法:打开“命令提示符”(右键以管理员身份打开),输入“net stop mysql80”(这个80是之前设置的端口号,可能每个人不一样)就关闭了;输入“net start mysql80”就打开了
连接MySQL
第一种方法:直接打开“MySQL 8.0 Command Line Client”,然后输入密码
第二种方法:打开“命令提示符”(右键以管理员身份打开),输入“mysql -u root -p”
退出:输入“exit”
一些简单命令
叮叮叮注意:
- 每个命令都要以分号结尾
- 命令不区分大小写,大写是为了便于阅读
\c:退出当前命令
show databases:查看数据库
use 数据库名字:进入数据库
show tables:查看当前数据库的表
show tables from 数据库名字:查看某个数据库里面的表,但是没有进入这个数据库
创建数据库(Schema)
CREATE DATABASE [SchemaName] DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
\\例如:创建一个教育管理系统数据库
CREATE DATABASE edu_managerment_sys DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
不提倡修改Schema,要想修改Schema,最好的方式就是新建一个Schema,然后从旧的Schema中将数据导入到新建的Schema中
删除数据库
DROP DATABASE [SchemaName];
创建表
CREATE TABLE table_name (column_name column_type [constraint]) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注意:
ENGINE=InnoDB: 表示用InnoDB引擎来创建表。
DEFAULT CHARSET=utf8:表示设置表的默认编码。
constraint: 表示的是一种约束,可省略,后面会详细介绍。
例如,创建一个学生表:student
CREATE TABLE student (
id INT NOT NULL,
name VARCHAR(100) NOT NULL,
age INT NOT NULL,
sex VARCHAR(100) NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
显示表: SHOW TABLES;
+----------------------------------------+
| Tables_in_education_managerment_system |
+----------------------------------------+
| student |
+----------------------------------------+
1 row in set (0.00 sec)
查看表内容 :select * from [表名称];
+------+------+-----+-----+
| id | name | age | sex |
+------+------+-----+-----+
| 1 | 张三 | 18 | 男 |
+------+------+-----+-----+
修改表
修改表主要有关于表的信息修改和表的列信息修改:
修改表名称
RENAME TABLE [old_table] TO [new_table];
//例如修改student表为student_info:
RENAME TABLE student TO student_info;
//返回结果:
Query OK, 0 rows affected (0.00 sec)
修改列
//增加列:
ALTER TABLE table_name ADD COLUMN column_name column_type;
//修改列类型
ALTER TABLE table_name MODIFY column_name column_type;
//删除列
ALTER TABLE table_name DROP COLUMN column_name;
//例如:
ALTER TABLE student_info ADD COLUMN class_name VARCHAR(100);
ALTER TABLE student_info MODIFY class_name INT;
ALTER TABLE student_info DROP COLUMN class_name;
删除表
DROP TABLE table_name;
插入数据:
给表的指定字段插入数据 (语法:INSERT INTO 表名(属性 1,属性 2,...,属性 n) VALUES(值 1,值 2,值 3,...,值 n) )
insert into student (id,name,age,sex) values(001,'张三',18,'男');
更新数据:
修改更新数据(UPDATE 表名 SET 属性名 1=取值 1,属性名 2=取值 2,...,属性名 n=取值 n WHERE 条件表达式)
update student set id='001' where age=18;
删除某行数据:
DELETE FROM 表名 WHERE 主键 = ‘具体值'
检索表内容
- 检索表里所有内容:
SELECT * FROM table_name;
- 检索表里的多个列:
SELECT column1_name, column2_name, ... FROM table_name;
- 检索结果消除重复:
SELECT DISTINCT column1_name, column2_name,... FROM table_name;
- 检索指定开始行(m)后和返回的行数(n):
SELECT column1, column2, ... FROM table_name LIMIT m, n;
- 用LIMIT可以实现分页
过滤数据
SELECT [*|columns] FROM table_name WHERE condition expression;
条件表达式有以下几种
1. 条件操作符:
条件操作符是WHERE子句根据条件过滤数据的根本,常见的条件操作符有下面几种:
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
BETWEEN | 在指定的两个值之间 |
IS NOT NULL | 为空/不为空 |
说明:
- 是否为空判断用IS NOT NULL,与!=''是不同的含义,前者是数值本身是空,后者表示字符串为'',不要混淆。
- 他们之间的优先级和JAVA等语言里面的优先级一致,这里不再赘述。
举个例子: 查找学生表中年龄大于18岁的学生:
mysql> SELECT * FROM student_info WHERE age > 18;
+----+--------+-----+-----+
| id | name | age | sex |
+----+--------+-----+-----+
| 2 | 李四 | 20 | 女 |
| 3 | 王五 | 30 | 男 |
+----+--------+-----+-----+
2 rows in set (0.05 sec)
查找某个时间之前(之后)
select * from table where post_time > '2009-01-20'
2. 逻辑操作符
如果想查找学生表中年龄大于18岁的男性学生,怎么办?这里就要用到逻辑操作符了,常见的有下面几种:
- AND:与操作符,用在WHERE子句中的关键字,用来指示检索满足所有给定的条件的行。
- OR:或操作符,用来指示检索匹配任一给定的行。
- NOT:非操作符,该操作符有且只有一个功能,那就是否定它之后所跟任何条件。
上面的例子: 查找学生表中年龄大于18岁的男性学生
mysql> SELECT * FROM student_info WHERE age > 18 AND sex = '男';
+----+--------+-----+-----+
| id | name | age | sex |
+----+--------+-----+-----+
| 3 | 王五 | 30 | 男 |
+----+--------+-----+-----+
1 row in set (0.01 sec)
3. 其他操作符:
除了上面的两种操作符之外,还有几种操作符比较常用:
-
IN操作符:
IN操作符用来指定条件范围,范围中的每个条件都可以匹配,具体语法就是取值清单包括在括号里面:
SELECT * FROM table_name WHERE column_name IN (value1, value2, value3,....);
例如: 查找年龄为20岁和30岁的学生:
mysql> SELECT * FROM student_info WHERE age IN (20, 30); +----+--------+-----+-----+ | id | name | age | sex | +----+--------+-----+-----+ | 2 | 李四 | 20 | 女 | | 3 | 王五 | 30 | 男 | +----+--------+-----+-----+ 2 rows in set (0.00 sec)
-
LIKE操作符:
假如想获取学生表中名字里面带有‘王’字的学生,怎么办?这就要用到LIKE操作符了:
SELECT * FROM table_name WHERE column_name LIKE 'value';
LIKE关键字后面经常有两种通配符:
- 百分号(%): 表示任何字符出现任意次数,可以匹配一个或者多个。
- 下划线(_): 匹配任意字符,只能匹配单个字符。
例如: 学生表里面有两个姓王的学生:王五和王明刚,如果用百分号和下划线匹配,则为:
mysql> SELECT * FROM student_info WHERE name LIKE '王%'; +----+-----------+-----+-----+ | id | name | age | sex | +----+-----------+-----+-----+ | 3 | 王五 | 30 | 男 | | 4 | 王明刚 | 40 | 男 | +----+-----------+-----+-----+ 2 rows in set (0.00 sec) mysql> SELECT * FROM student_info WHERE name LIKE '王_'; +----+--------+-----+-----+ | id | name | age | sex | +----+--------+-----+-----+ | 3 | 王五 | 30 | 男 | +----+--------+-----+-----+ 1 row in set (0.00 sec)
备注:
正如所见,MySQL的通配符很有用,但这种功能是有代价的:通配符搜索的处理一般要比前面讨论的其他搜索花更长时间。这里给出一些使用通配符的要领:
- 不要过度使用通配符,如果其他操作符能够达到同样的目的,应该使用其他操作符。
- 在确实需要使用通配符时,除非有绝对必要,否则不要把他们用在搜索模式的开始处。
- 仔细注意通配符的位置,如果放错地方,可能不会返回想要的数据。
参考链接:
排序检索
排序是我们经常需要用到的功能,比如学生成绩的排名,年龄的排名等,语法如下:
SELECT * FROM table_name ORDER BY column [ASC|DESC];
说明:
- ASC表示升序,可以省略,DESC表示降序,不可省略。
- 如果要对多个字段进行排序,可以在ORDER BY后面依次增加多个列,会依次按照多个列进行排序。
- 排序可以和LIMIT关键字进行组合来找到一个列中最高或者最低的值。
- 排序通常位于WHERE子句的后面。
举个例子: 查找学生表中年龄最大的男生:
mysql> SELECT * FROM student_info WHERE sex = '男' ORDER BY age DESC LIMIT 1;
+----+-----------+-----+-----+
| id | name | age | sex |
+----+-----------+-----+-----+
| 4 | 王明刚 | 40 | 男 |
+----+-----------+-----+-----+
1 row in set (0.01 sec)
数据处理
本节的主要目标是掌握对结果集处理的函数,了解分组的相关知识。
别名
有时候,我们对于SELECT查询的结果出现未命名的列,比如两个列的组合,或者学生成绩表中的成绩的平均数等,这些列是不存在与数据库中的,而是通过已有列经过计算和处理产生的,是具有一定的业务逻辑含义的。为了解决这个问题,SQL支持列别名。
别名(alias): 是一个字段或值的替换名,通常是为了表达该字段或者值所代表的业务意义而存在的。 通常用AS关键字来实现:
SELECT value AS alias FRTOM table_name;
注意:
- 别名和原来的列或者值名具有同等的价值。
- 别名还可以应用在原来的列或者值得名字不符合专业性的要求的情况下使用。
例如:查询学生表中学生的姓名(name),期望用别名(student_name)来表示:
mysql> SELECT id, name AS student_name FROM student_info;
+----+--------------+
| id | student_name |
+----+--------------+
| 1 | 小明 |
| 2 | 李四 |
| 3 | 王五 |
| 4 | 王明刚 |
+----+--------------+
4 rows in set (0.05 sec)
计算
算术运算
有时候我们需要对查询结果进行一些计算,比如有下面的订单表(orders):
production_id | quantity | item_price |
---|---|---|
1 | 3 | 55 |
2 | 4 | 34 |
3 | 6 | 65 |
4 | 8 | 80 |
想要获取每种商品的总价,就需要单价*数量,这就涉及到算术运算符了,常见的算术运算符如下:
操作符 | 描述 |
---|---|
+ | 加法 -添加任一侧上的操作符的值 |
- | 减法 - 从左边减去右边操作数的操作 |
* | 乘法 - 操作符两侧的值相乘 |
/ | 除 - 将左边除右边的操作数(取模) |
% | 模量 - 将左边用右手操作,并返回操作数的余数 |
上面的需求,可以这样实现:
mysql> SELECT production_id, quantity, price, quantity*price AS total_price FROM orders;
+---------------+----------+-------+-------------+
| production_id | quantity | price | total_price |
+---------------+----------+-------+-------------+
| 1 | 3 | 55 | 165 |
| 2 | 4 | 34 | 136 |
| 3 | 6 | 65 | 390 |
| 4 | 8 | 80 | 640 |
+---------------+----------+-------+-------------+
4 rows in set (0.00 sec)
拼接
与其他编程语言不同的是,如果要将多个字符串链接起来,其他编程语言会用+来拼接,但是SQL中却需要用CONCAT()来拼接:
CONCAT(str1,str2,…);
例如:
mysql> SELECT CONCAT('M', 'y', 'S', 'Q', 'L');
+---------------------------------+
| CONCAT('M', 'y', 'S', 'Q', 'L') |
+---------------------------------+
| MySQL |
+---------------------------------+
1 row in set (0.01 sec)
注意: CONCAT_WS(separator,str1,str2,…) 代表 CONCAT With Separator ,是CONCAT()的特殊形式。 第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。
处理函数
使用MySQL自带的函数可以在处理一些特殊需求的时候更加方便,更加游刃有余,常用的处理函数大体上有下面三类:
1. 文本处理函数
常用的文本处理函数如下:
名称 | 调用示例 | 示例结果 | 描述 |
---|---|---|---|
LEFT | LEFT('abc123', 3) | abc | 返回从左边取指定长度的子串 |
RIGHT | RIGHT('abc123', 3) | 123 | 返回从右边取指定长度的子串 |
LENGTH | LENGTH('abc') | 3 | 返回字符串的长度 |
LOWER | LOWER('ABC') | abc | 返回小写格式字符串 |
UPPER | UPPER('abc') | ABC | 返回大写格式字符串 |
LTRIM | LTRIM(' abc') | abc | 将字符串左边空格去除后返回 |
RTRIM | RTRIM('abc ') | abc | 将字符串右边空格去除后返回 |
TRIM | TRIM(' abc ') | Abd | 将字符串左右两边的空格去除后返回 |
SUBSTRING | SUBSTRING('abc123', 2, 3) | bc1 | 从字符串第2位开始截取3位字符 |
其他的文本处理函数请参考:String Functions
2. 日期和时间处理函数
一般,应用程序不使用用来存储日期和时间的格式,因此日期和时间函数总是被用来读取、统计和处理这些值。由于这个原因,日期和时间函数在MySQL语言中具有重要的作用。
常见的日期处理函数有下面几种:
函数 | 描述 |
---|---|
NOW() | 返回当前的日期和时间 |
CURDATE() | 返回当前的日期 |
CURTIME() | 返回当前的时间 |
DATE() | 提取日期或日期/时间表达式的日期部分 |
EXTRACT() | 返回日期/时间按的单独部分 |
DATE_ADD() | 给日期添加指定的时间间隔 |
DATE_SUB() | 从日期减去指定的时间间隔 |
DATEDIFF() | 返回两个日期之间的天数 |
DATE_FORMAT() | 用不同的格式显示日期/时间 |
ADDDATE() | 增加一个日期(天,周等) |
ADDTIME() | 增加一个时间(时,分等) |
DAY() | 返回一个日期的天数部分 |
YEAR() | 返回一个日期的年份部分 |
其他日期处理函数请参考: Date and Time Functions
3. 数值处理函数
数值处理函数仅仅处理数值数据,这些函数一般主要用于代数,几何,三角运算等,因此没有字符串或者时间处理函数那么使用频繁,但是仍旧需要了解:
函数 | 说明 |
---|---|
Abs() | 返回一个数的绝对值 |
Cos() | 返回一个角度的余弦 |
Exp() | 返回一个数的指数值 |
Mod() | 返回除操作的余数 |
Pi() | 返回圆周率 |
Rand() | 返回一个随机数 |
Sin() | 返回一个角度的正弦 |
Sqrt() | 返回一个数的平方根 |
Tan() | 返回一个数的正切 |
相关数值处理函数请参考:Numeric Functions and Operators
聚集函数
我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了专门的函数。使用这些函数,MySQL查询可用于检索数据,以便分析和报表生成。
聚集函数:运行在行组上,计算和返回单个值得函数。
常见的聚集函数如下:
AVG函数
此函数通过对表中行数计数并计算特定列之和,求得该列平均值。AVG()可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。
例如:获取订单表中产品的均价:
mysql> SELECT AVG(price) AS avg_price FROM orders;
+-----------+
| avg_price |
+-----------+
| 58.5 |
+-----------+
1 row in set (0.01 sec)
COUNT函数
此函数用来进行计数,可利用COUNT()确定表中行的数目或符合特定条件的行的数目。有两种使用方式:
- 使用COUNT(*)对表中行的数目进行计数,不管列中包含的是控制还是非控制。
- 使用COUNT(column)对特定列中具有值的行进行比较,忽略NULL值。
例如:统计订单表中的所有记录总数:
mysql> SELECT COUNT(*) AS num_cust FROM orders;
+----------+
| num_cust |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
MAX/MIN函数
MAX()函数用来返回指定列中的最大值,MIN()函数与其相反,返回指定列的最小值。需要注意两点:
- MySQL允许他们用来返回任意列中的最大/最小值,用于文本数据时,如果数据按照相应的列排序,则返回最后/第一行。
- 此函数忽略值为NULL的行。
例如:获取订单表中最高和最低价格:
mysql> SELECT MAX(price) AS highest_price, MIN(price) AS lowest_price FROM orders;
+---------------+--------------+
| highest_price | lowest_price |
+---------------+--------------+
| 80 | 34 |
+---------------+--------------+
1 row in set (0.00 sec)
SUM函数
此函数用来返回指定列的和。此函数也会忽略值为NULL的行。
例如:计算订单表中所有产品的总价:
mysql> SELECT SUM(quantity*price) AS total_price FROM orders;
+-------------+
| total_price |
+-------------+
| 1331 |
+-------------+
1 row in set (0.00 sec)
分组
上面我们学习了聚合函数,其实很多聚合函数是和分组一起使用的,比如,想要统计学生表中男生和女生的个数;这就要使用分组了:
SELECT column_name(s) FROM table_name [WHERE condition] GROUP BY column_name(s) [ORDER BY column_name(s)];
说明:
- group by子句可以包含任意数目的列(使得对分组进行嵌套,为数据分组提供更细致的控制);
- 如果在group by子句中嵌套分组,数据将在最后规定的分组上进行汇总,即:建立分组时,指定的所有列都一起计算(所以不能从个别列取回数据);
- group by子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数),如果在select中使用表达式,则必须在group by子句中指定相同的表达式(不能使用别名);
- 除了聚集计算语句外,select中每个列都必须在group by子句中给出;
- 如果分组列中具有null值,则null将作为一个分组返回(如果列中有多行null值,他们将分为一组);
- group by子句必须出现在where子句之后,order by子句之前;
例如:统计学生表中男生和女生的个数
mysql> SELECT sex, COUNT(*) AS sex_count FROM student_info GROUP BY sex;
+-----+-----------+
| sex | sex_count |
+-----+-----------+
| 女 | 1 |
| 男 | 3 |
+-----+-----------+
2 rows in set (0.00 sec)
高级查询
本节主要掌握子查询、联结查询、组合查询的语法,了解全文本搜索的相关知识和概念。
子查询
前面学习了各种查询,都是从单一的表中查询相关数据,这是最基本的查询。我们都知道,MySQL是关系型数据库,如果要从多个相关联表中查询数据,该怎么办?比如下面的例子:
学生信息表:
+----+-----------+-----+-----+
| id | name | age | sex |
+----+-----------+-----+-----+
| 1 | 小明 | 18 | 男 |
| 2 | 李四 | 20 | 女 |
| 3 | 王五 | 30 | 男 |
| 4 | 王明刚 | 40 | 男 |
+----+-----------+-----+-----+
成绩表:
+------+------------+---------+-------+
| id | student_id | subject | score |
+------+------------+---------+-------+
| 1 | 1 | 语文 | 80 |
| 2 | 2 | 语文 | 70 |
+------+------------+---------+-------+
现在要获取小明的语文成绩,需要查询两步:
- 首先从学生表中找到姓名为小明的同学的id。
- 然后通过小明同学的id从成绩表里面获取他的语文成绩。
实现SQL为:
SELECT score FROM score WHERE subject = '语文' AND student_id = (
SELECT id FROM student_info WHERE name = '小明'
);
结果为:
+-------+
| score |
+-------+
| 80 |
+-------+
1 row in set (0.01 sec)
上面的例子用了子查询来完成:
子查询:允许把一个查询嵌套在另一个查询当中的查询。
子查询分为内部查询和外部查询。内部查询就是上面例子中的:SELECT id FROM student_info WHERE name = '小明';外部查询就是:SELECT score FROM score WHERE...。
从上面的例子可以看出,子查询有下面几种优势:
- 子查询有清晰的查询过程,先从内部查询开始,在到外部查询,依次从里到位的顺序对代码可读性和可理解性较好。
- 使用子查询与GROUP BY可以比较方便的创建一些计算字段。
- 对于两个或者多个没有直接物理关联的表(可能存在着一些逻辑关联),子查询比较容易实现查询。
凡事都有利弊,子查询也有缺陷:
- 当查询的表过多(超过3个),那么嵌套的查询就比较复杂,反而降低了可读性。
- 子查询是从里到外的查询,所以性能比较差。
- 外部的查询的返回结果不能包括内部查询的结果,比如想获取小明的语文成绩和年龄等就不能用子查询实现。
参考链接:
联结查询
从上面的子查询可以看出,子查询的这些缺点导致它的使用频率并不高,下面的联结查询能够弥补子查询的缺点。
简单地说,联结就是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。 其意义在于:在用户查看数据的时候, 需要显示的数据来自多张表。
内联结
又叫等值联结,基于两个表之间的相等测试,返回两个或者多个表之间相等关系的数据,用数学关系来看,相当于求交集。
语法如下:
SELECT * FROM table1 AS t1 INNER JOIN table2 AS t2 ON t1.column = t2.column;
说明:
- 查询过程:从左表中取出每一条记录,去右表中与所有的记录进行匹配: 匹配必须是某个条件在左表中与右表中相同最终才会保留结果,否则不保留.
- 字段别名以及表别名的使用: 在查询数据的时候,不同表有同名字段,这个时候需要加上表名才能区分, 而表名太长, 通常可以使用别名.
- 内连接还可以使用where代替on关键字,但效率差很多。
例如: 查询学生表中有成绩的学生:
mysql> SELECT s1.name, s2.subject, s2.score FROM student_info AS s1 INNER JOIN score AS s2 ON s1.id = s2.student_id;
+--------+---------+-------+
| name | subject | score |
+--------+---------+-------+
| 小明 | 语文 | 80 |
| 李四 | 语文 | 70 |
+--------+---------+-------+
2 rows in set (0.00 sec)
从查询的结果可以看出,仅仅返回了两张表中都有的数据。
外联结
以某张表为主,取出里面的所有记录, 然后每条与另外一张表进行连接: 不管能不能匹配上条件,最终都会保留: 能匹配,正确保留; 不能匹配,其他表的字段都置空NULL.
外联结分为两种:
1. 左外联结(左联结):
以左边为主表,返回左表中的所有数据:
语法为:
SELECT * FROM table1 AS t1 LEFT JOIN table2 AS t2 ON t1.column = t2.column;
例如:返回所有学生的成绩:
mysql> SELECT s1.name, s2.subject, s2.score FROM student_info AS s1 LEFT JOIN score AS s2 ON s1.id = s2.student_id;
+-----------+---------+-------+
| name | subject | score |
+-----------+---------+-------+
| 小明 | 语文 | 80 |
| 李四 | 语文 | 70 |
| 王五 | NULL | NULL |
| 王明刚 | NULL | NULL |
+-----------+---------+-------+
4 rows in set (0.00 sec)
2. 右外联结(右联结):
以右边为主表,返回右表中的所有数据:
语法:
SELECT * FROM table1 AS t1 RIGHT JOIN table2 AS t2 ON t1.column = t2.column;
交叉联结:
从一张表中循环取出每一条记录, 每条记录都去另外一张表进行匹配: 匹配一定保留(没有条件匹配), 而连接本身字段就会增加(保留),最终形成的结果叫做: 笛卡尔积。
语法:
SELECT * FROM table1 AS t1 CROSS JOIN table2 AS t2;
此联结经常用不到,所以此处不做深入讲解。
自联结
有时需要在同一张表中进行联结条件的匹配或字段比较,可以使用自联结。
语法:
SELECT * FROM table t1, table t2 WHERE t1.column1=t2.column2;
此联结经常用不到,所以此处不做深入讲解。
参考链接:
组合查询
多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这些组合查询通常称为并(union)或符合查询(compound query)。
有两种基本情况,其中需要使用组合查询:
- 在单个查询中,从不同表中返回类似结构的数据。
- 对单个表执行多个查询,按照单个查询返回数据。
多数情况下,任何具有多个WHERE子句的SELECT语句都可以作为一个组合查询给出,这两种技术在不同的查询中性能也不同。
语法:
SELECT * FROM table1 WHERE condition
UNION
SELECT * FROM table2 WHERE condition;
说明:
- UNION必须由两条或者两条以上的SELECT语句组成,语句之间用关键字UNION分隔。
- UNION中的每个查询必须包含相同的列、表达式或聚集函数。
- UNION中的每个SELECT语句返回的列类型必须兼容。可以不必完全相同,但是可以隐式转换。
- UNION默认会消除重复的行,如果要返回所有行:请用UNION ALL。
- 再用UNION查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT之后。
例如:查询学生表中年龄超过20岁或者是男生的。
mysql> SELECT * FROM student_info WHERE age > 20
-> UNION
-> SELECT * FROM student_info WHERE sex = '男';
+----+-----------+-----+-----+
| id | name | age | sex |
+----+-----------+-----+-----+
| 3 | 王五 | 30 | 男 |
| 4 | 王明刚 | 40 | 男 |
| 1 | 小明 | 18 | 男 |
+----+-----------+-----+-----+
3 rows in set (0.05 sec)
当然,也可以用一个SELECT语句加上WHERE条件来实现:
mysql> SELECT * FROM student_info WHERE age > 20 or sex = '男';
+----+-----------+-----+-----+
| id | name | age | sex |
+----+-----------+-----+-----+
| 1 | 小明 | 18 | 男 |
| 3 | 王五 | 30 | 男 |
| 4 | 王明刚 | 40 | 男 |
+----+-----------+-----+-----+
3 rows in set (0.00 sec)
参考链接: