MySQL数据高级语句
文章目录
MySQL查询
在对 MySQL 数据库的增、删、改、查操作有一定了解之后,就可以学习一些 SQL 语句的高级使用方法。SQL 语句的熟练使用,在平时的运维工作中可以提供不小的帮助,尤其是在一些规模较小的公司,运维身兼数职,可能会有不少数据库的相关工作。本章将从不 同的方面出发介绍 SQL 语句的高级运用方法。
【1】按关键字排序
ORDER BY A,B desc 指 A 用升序,B 用降序;
ORDER BY A asc,B desc 指 A 用升序,B 用降序;
ORDER BY A desc,B desc 指 A 用降序,B 用降序;
mysql> select * from student1;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
+----+----------+-------+--------+
4 rows in set (0.00 sec)
(1)升序排列
mysql> select * from student1 order by socre asc;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
| 2 | zhangsan | 88.00 | 1 |
| 1 | lisi | 99.00 | 1 |
+----+----------+-------+--------+
4 rows in set (0.00 sec)
(2)降序排列
mysql> select * from student1 order by socre desc;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 4 | qianba | 78.00 | 3 |
| 3 | tianqi | 77.00 | 2 |
+----+----------+-------+--------+
4 rows in set (0.00 sec)
(3)和条件配合使用降序排列
mysql> select * from student1 where course=1 order by socre desc;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
+----+----------+-------+--------+
2 rows in set (0.00 sec)
【2】对结果进行分组
通过 SQL 查询出来的结果,还可以对其进行分组,使用 GROUP BY 语句来实现。GROUP BY 从字面上看,是以 BY 后面的内容对查询出的数据进行分组,就是将一个“数据集”划分成若干个“小区域”,然后针对这些个“小区域”进行数据处理。GROUP BY 通常都是结合聚合函数一起使用的,常用的聚合函数包括:计数(COUNT)、求和(SUM)、求平均数(AVG)、最大值(MAX)、最小值(MIN),这些聚合函数的用法在后面函数小节会有更详细的讲解。GROUP BY 分组的时候可以按一个或多个字段对结果进行分组处理。
mysql> select name,socre,count(socre) from student1 where course=2 or course=3
group by socre order by socre desc;
+--------+-------+--------------+
| name | socre | count(socre) |
+--------+-------+--------------+
| qianba | 78.00 | 1 |
| tianqi | 77.00 | 1 |
+--------+-------+--------------+
2 rows in set (0.00 sec)
mysql> select name,socre,max(socre) from student1 where course=1 group by course;
+------+-------+------------+
| name | socre | max(socre) |
+------+-------+------------+
| lisi | 99.00 | 99.00 |
+------+-------+------------+
1 row in set (0.00 sec)
mysql> select name,socre,max(socre) from student1 where course=1 group by name;
+----------+-------+------------+
| name | socre | max(socre) |
+----------+-------+------------+
| lisi | 99.00 | 99.00 |
| zhangsan | 88.00 | 88.00 |
+----------+-------+------------+
2 rows in set (0.00 sec)
mysql> select name,socre,max(socre) from student1 where course=1 group by socre;
+----------+-------+------------+
| name | socre | max(socre) |
+----------+-------+------------+
| zhangsan | 88.00 | 88.00 |
| lisi | 99.00 | 99.00 |
+----------+-------+------------+
2 rows in set (0.00 sec)
【3】限制结果条目
在使用 MySQL SELECT 语句进行查询时,结果集返回的是所有匹配的记录。有时候仅需要返回第一行或者前几行,这时候就需要用到 LIMIT 子句。
格式:
SELECT column1, column2, ... FROM table_name LIMIT [位置偏移量], number
第一个参数位置偏移量从0开始,第二个参数number是设置返回记录行的最大数目。
mysql> select * from student1;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
+----+----------+-------+--------+
4 rows in set (0.00 sec)
//查询前三个用户
mysql> select * from student1 limit 3;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
+----+----------+-------+--------+
3 rows in set (0.00 sec)
//查询从第二个用户开始的两个用户
mysql> select * from student1 limit 1,2;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
+----+----------+-------+--------+
2 rows in set (0.00 sec)
【4】设置别名
在 MySQL 查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者多次使用相同的表,可以给字段列或表设置别名。使用的时候直接使用别名,简洁明了,增强可读性。设置别名使用 AS 语句。其中的关键字as可以省略。
字段别名设置格式:
SELECT 字段名 AS 别名 FROM 表名;
举例说明
mysql> select name,socre,max(socre) as '最高成绩' from student1 where course=1 group by soocre;
+----------+-------+--------------+
| name | socre | 最高成绩 |
+----------+-------+--------------+
| zhangsan | 88.00 | 88.00 |
| lisi | 99.00 | 99.00 |
+----------+-------+--------------+
2 rows in set (0.00 sec)
表别名设置格式:
SELECT 字段名 FROM 表名 AS 表别名;
//两表相连
mysql> select * from student1 inner join course on student1.course=course.id;
+----+----------+-------+--------+----+--------+---------+
| id | name | socre | course | id | name | teacher |
+----+----------+-------+--------+----+--------+---------+
| 1 | lisi | 99.00 | 1 | 1 | 语文 | NULL |
| 2 | zhangsan | 88.00 | 1 | 1 | 语文 | NULL |
| 3 | tianqi | 77.00 | 2 | 2 | 数学 | NULL |
| 4 | qianba | 78.00 | 3 | 3 | 英语 | NULL |
+----+----------+-------+--------+----+--------+---------+
4 rows in set (0.00 sec)
//student1的别名是stu1,course的别名是c
mysql> select * from student1 as stu1 inner join course c on stu1.course=c.id;
+----+----------+-------+--------+----+--------+---------+
| id | name | socre | course | id | name | teacher |
+----+----------+-------+--------+----+--------+---------+
| 1 | lisi | 99.00 | 1 | 1 | 语文 | NULL |
| 2 | zhangsan | 88.00 | 1 | 1 | 语文 | NULL |
| 3 | tianqi | 77.00 | 2 | 2 | 数学 | NULL |
| 4 | qianba | 78.00 | 3 | 3 | 英语 | NULL |
+----+----------+-------+--------+----+--------+---------+
4 rows in set (0.00 sec)
【5】通配符
通配符主要用于替换字符串中的部分字符,通过部分字符的匹配将相关结果查询出来。通常通配符都是跟 LIKE 一起使用的,并协同 WHERE 子句共同来完成查询任务。常用的通配符有两个,分别是:
%:百分号表示零个、一个或多个字符
_:下划线表示单个字符
mysql> select * from student1 where name like '%zhang_a_';
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 2 | zhangsan | 88.00 | 1 |
+----+----------+-------+--------+
1 row in set (0.00 sec)
【6】子查询(内查询、嵌套查询)
查询语句里面还嵌套着另一个查询语 句。子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一 步的查询过滤。子查询不仅可以在 SELECT 语句中使用,在 INERT、UPDATE、DELETE 中也同样适用。在嵌套的时候,子查询内部还可以再次嵌套新的子查询,也就是说可以多层嵌套。子查询操作符:
(1)IN 用来判断某个值是否在给定的结果集中
格式为:
<表达式> [NOT] IN <子查询>
mysql> select * from student1 where course in (
select course from course where name='语文'
);
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
+----+----------+-------+--------+
4 rows in set (0.00 sec)
mysql> select * from student1 where course not in (
select course from course where name='语语文'
);
Empty set (0.00 sec)
(2)子查询上也可以使用比较运算符(=、<、>、>=、<=)
这些运算符主要是对运算符前面的表达式和后面的子查询进行比较运算。
mysql> select * from student1 where name='qianba';
+----+--------+-------+--------+
| id | name | socre | course |
+----+--------+-------+--------+
| 4 | qianba | 78.00 | 3 |
+----+--------+-------+--------+
1 row in set (0.00 sec)
(3)EXIST 这个关键字
在子查询时,主要用于判断子查询的结果集是否为空。如果不为空, 则返回 TRUE;反之,则返回 FALSE。
mysql> select min(socre) '最低分' from student1 where exists(
select * from student1 where name='tianba'
);
+-----------+
| 最低分 |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
mysql> select min(socre) '最低分' from student1 where exists(
select * from student1 where name='zhangsan'
);
+-----------+
| 最低分 |
+-----------+
| 66.00 |
+-----------+
1 row in set (0.00 sec)
(4)UPDATE 、delete语句也可以使用子查询。
UPDATE 内的子查询,在 set 更新内容时,可以是单独的一列,也可以是多列。
mysql> select * from student1;
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
| 5 | tianbi | 66.00 | 3 |
+----+----------+-------+--------+
5 rows in set (0.00 sec)
mysql> update student1 set socre=socre+5 where socre>=88;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from student1 where socre>=88;
+----+----------+--------+--------+
| id | name | socre | course |
+----+----------+--------+--------+
| 1 | lisi | 104.00 | 1 |
| 2 | zhangsan | 93.00 | 1 |
+----+----------+--------+--------+
2 rows in set (0.00 sec)
【7】null值
在 SQL 语句使用过程中,经常会碰到 NULL 这几个字符。通常使用 NULL 来表示缺失的值,也就是在表中该字段是没有值的。如果在创建表时,限制某些字段不为空,则可以使用 NOT NULL 关键字,不使用则默认可以为空。在向表内插入记录或者更新记录时,如果该字段没有 NOT NULL 并且没有值,这时候新记录的该字段将被保存为 NULL。
1】null和空值得比较
(1)空值就是在表的字段中存储空字符(‘’),空值的长度为 0,不占用空间的;而 NULL 值的长度是 NULL,是占用空间的。
(2)IS NULL 或者 IS NOT NULL,是用来判断字段是不是为 NULL 或者不是 NULL,不能查出是不是空值的。
(3)空值的判断使用=’’或者<>’’来处理。
(4)在通过 count()计算有多少记录数时,如果遇到 NULL 值会自动忽略掉,遇到空值会加入到记录中进行计算。
mysql> select * from student1;
+----+----------+--------+--------+----------+
| id | name | socre | course | teacher |
+----+----------+--------+--------+----------+
| 1 | lisi | 104.00 | 1 | yanglong |
| 2 | zhangsan | 93.00 | 1 | yanglong |
| 3 | tianqi | 77.00 | 2 | |
| 4 | qianba | 78.00 | 3 | NULL |
| 5 | tianbi | 66.00 | 3 | NULL |
+----+----------+--------+--------+----------+
5 rows in set (0.00 sec)
mysql> select * from student1 where teacher is null;
+----+--------+-------+--------+---------+
| id | name | socre | course | teacher |
+----+--------+-------+--------+---------+
| 4 | qianba | 78.00 | 3 | NULL |
| 5 | tianbi | 66.00 | 3 | NULL |
+----+--------+-------+--------+---------+
2 rows in set (0.00 sec)
mysql> select * from student1 where teacher is not null;
+----+----------+--------+--------+----------+
| id | name | socre | course | teacher |
+----+----------+--------+--------+----------+
| 1 | lisi | 104.00 | 1 | yanglong |
| 2 | zhangsan | 93.00 | 1 | yanglong |
| 3 | tianqi | 77.00 | 2 | |
+----+----------+--------+--------+----------+
3 rows in set (0.00 sec)
【8】数据库正则表达式
MySQL 的正则表达式使用 REGEXP 这个关键字来指定正则表达式的匹配模式
(1)以特定字符串开头
mysql> select * from student1 where name regexp '^zhang';
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 2 | zhangsan | 88.00 | 1 |
+----+----------+-------+--------+
1 row in set (0.00 sec)
(2)以特定字符串结尾
mysql> select * from student1 where name regexp 'si$';
+----+------+-------+--------+
| id | name | socre | course |
+----+------+-------+--------+
| 1 | lisi | 99.00 | 1 |
+----+------+-------+--------+
1 row in set (0.00 sec)
(3)包含指定字符串
mysql> select * from student1 where name regexp 'ba';
+----+--------+-------+--------+
| id | name | socre | course |
+----+--------+-------+--------+
| 4 | qianba | 78.00 | 3 |
+----+--------+-------+--------+
1 row in set (0.00 sec)
(4)以“.”字符串中的任意一个字符
mysql> select * from student1 where name regexp 'tian.';
+----+--------+-------+--------+
| id | name | socre | course |
+----+--------+-------+--------+
| 3 | tianqi | 77.00 | 2 |
| 5 | tianbi | 66.00 | 3 |
+----+--------+-------+--------+
2 rows in set (0.00 sec)
(5)匹配包含“或”关系的记录
mysql> select * from student1 where name regexp 'qi|bi';
+----+--------+-------+--------+
| id | name | socre | course |
+----+--------+-------+--------+
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
| 5 | tianbi | 66.00 | 3 |
+----+--------+-------+--------+
3 rows in set (0.00 sec)
(6)“*”匹配前面字符的任意多次
mysql> select * from student1 where name regexp 'qi*';
+----+--------+-------+--------+
| id | name | socre | course |
+----+--------+-------+--------+
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
+----+--------+-------+--------+
2 rows in set (0.00 sec)
(7)“+”匹配前面字符至少一次
mysql> select * from student1 where name regexp 'qi+';
+----+--------+-------+--------+
| id | name | socre | course |
+----+--------+-------+--------+
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
+----+--------+-------+--------+
2 rows in set (0.00 sec)
(8)匹配指定字符集中的一个
mysql> select * from student1 where name regexp '^[a-z]';
+----+----------+-------+--------+
| id | name | socre | course |
+----+----------+-------+--------+
| 1 | lisi | 99.00 | 1 |
| 2 | zhangsan | 88.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
| 5 | tianbi | 66.00 | 3 |
+----+----------+-------+--------+
5 rows in set (0.00 sec)
【9】数据库运算符
(1)算术运算符
mysql> select 1+2,2-1,2*2,2/2,4%3;
+-----+-----+-----+--------+------+
| 1+2 | 2-1 | 2*2 | 2/2 | 4%3 |
+-----+-----+-----+--------+------+
| 3 | 1 | 4 | 1.0000 | 1 |
+-----+-----+-----+--------+------+
1 row in set (0.00 sec)
mysql> select 1+2,2-1,2*2,2/2,4%3,(2+5)*5+3;
+-----+-----+-----+--------+------+-----------+
| 1+2 | 2-1 | 2*2 | 2/2 | 4%3 | (2+5)*5+3 |
+-----+-----+-----+--------+------+-----------+
| 3 | 1 | 4 | 1.0000 | 1 | 38 |
+-----+-----+-----+--------+------+-----------+
1 row in set (0.00 sec)
(2)比较运算符
mysql> select 2=4,2='2','e'=e,(2+5)=2*4,'r'=null;
ERROR 1054 (42S22): Unknown column 'e' in 'field list'
mysql> select 2=4,2='2','e'='e',(2+5)=2*4,'r'=null;
+-----+-------+---------+-----------+----------+
| 2=4 | 2='2' | 'e'='e' | (2+5)=2*4 | 'r'=null |
+-----+-------+---------+-----------+----------+
| 0 | 1 | 1 | 0 | NULL |
+-----+-------+---------+-----------+----------+
1 row in set (0.00 sec)
mysql> select 'kgc'<>'bdqn','khc'='kgc',1<>2,3=3,3!=3,null<>null;
+---------------+-------------+------+-----+------+------------+
| 'kgc'<>'bdqn' | 'khc'='kgc' | 1<>2 | 3=3 | 3!=3 | null<>null |
+---------------+-------------+------+-----+------+------------+
| 1 | 0 | 1 | 1 | 0 | NULL |
+---------------+-------------+------+-----+------+------------+
1 row in set (0.00 sec)
//在ASCII码中0是48,A是65,a是98
mysql> select 5>4,'a'>'A','a'>'b',4>=3,'z'>=null;
+-----+---------+---------+------+-----------+
| 5>4 | 'a'>'A' | 'a'>'b' | 4>=3 | 'z'>=null |
+-----+---------+---------+------+-----------+
| 1 | 0 | 0 | 1 | NULL |
+-----+---------+---------+------+-----------+
1 row in set (0.00 sec)
mysql> select 2 is null,'d' is not null,null is null;
+-----------+-----------------+--------------+
| 2 is null | 'd' is not null | null is null |
+-----------+-----------------+--------------+
| 0 | 1 | 1 |
+-----------+-----------------+--------------+
1 row in set (0.00 sec)
mysql> select 4 between 2 and 6,5 between 5 and 8,'c' between 'a' and 'd',
6 between 2 and 4;
+-------------------+-------------------+-------------------------+-------------------+
| 4 between 2 and 6 | 5 between 5 and 8 | 'c' between 'a' and 'd' | 6 between 2 and 4 |
+-------------------+-------------------+-------------------------+-------------------+
| 1 | 1 | 1 | 0 |
+-------------------+-------------------+-------------------------+-------------------+
1 row in set (0.00 sec)
mysql> select least(45,99,1,5,0,-1),least('A','s','x','v','f'),
greatest(45,99,1,5,0,-1),greatest(reatest('A','s','x','v','f');
+-----------------------+----------------------------+--------------------------+-------------------------------+
| least(45,99,1,5,0,-1) | least('A','s','x','v','f') | greatest(45,99,1,5,0,-1) | greatest('A','s','x','v','f') |
+-----------------------+----------------------------+--------------------------+-------------------------------+
| -1 | A | 99 | x |
+-----------------------+----------------------------+--------------------------+-------------------------------+
1 row in set (0.00 sec)
mysql> select 2 in (56,5,5,2,2),'c' not in ('a','b','c','d');
+-------------------+------------------------------+
| 2 in (56,5,5,2,2) | 'c' not in ('a','b','c','d') |
+-------------------+------------------------------+
| 1 | 0 |
+-------------------+------------------------------+
1 row in set (0.00 sec)
mysql> select 'bd' like 'bdqz','test' like 'te%','hot' not like '%te__';
+------------------+-------------------+------------------------+
| 'bd' like 'bdqz' | 'test' like 'te%' | 'hot' not like '%te__' |
+------------------+-------------------+------------------------+
| 0 | 1 | 1 |
+------------------+-------------------+------------------------+
1 row in set (0.00 sec)
(3)逻辑运算符
mysql> select not 2,!2,not 0,!(2-2);
+-------+----+-------+--------+
| not 2 | !2 | not 0 | !(2-2) |
+-------+----+-------+--------+
| 0 | 0 | 1 | 1 |
+-------+----+-------+--------+
1 row in set (0.00 sec)
mysql> select 2 and 3,4 && 0,0 && null, null && null;
+---------+--------+-----------+--------------+
| 2 and 3 | 4 && 0 | 0 && null | null && null |
+---------+--------+-----------+--------------+
| 1 | 0 | 0 | NULL |
+---------+--------+-----------+--------------+
1 row in set (0.00 sec)
mysql> select 1 or 1,1 or 0,0 || null, null || null,0 || 0;
+--------+--------+-----------+--------------+--------+
| 1 or 1 | 1 or 0 | 0 || null | null || null | 0 || 0 |
+--------+--------+-----------+--------------+--------+
| 1 | 1 | NULL | NULL | 00 |
+--------+--------+-----------+--------------+--------+
1 row in set (0.00 sec)
mysql> select 1 xor 1,1 xor 0,0 xor null, null xor null,0 xor 0;
+---------+---------+------------+---------------+---------+
| 1 xor 1 | 1 xor 0 | 0 xor null | null xor null | 0 xor 0 |
+---------+---------+------------+---------------+---------+
| 0 | 1 | NULL | NULL | 0 |
+---------+---------+------------+---------------+---------+
1 row in set (0.00 sec)
(4)位运算符
mysql> select 10 & 15,10 | 15,10 ^ 15,~15;
+---------+---------+---------+----------------------+
| 10 & 15 | 10 | 15 | 10 ^ 15 | ~15 |
+---------+---------+---------+----------------------+
| 10 | 15 | 5 | 18446744073709551600 |
+---------+---------+---------+----------------------+
1 row in set (0.00 sec)
mysql> select 10 & 15,10 | 15,10 ^ 15,10 & ~15;
+---------+---------+---------+----------+
| 10 & 15 | 10 | 15 | 10 ^ 15 | 10 & ~15 |
+---------+---------+---------+----------+
| 10 | 15 | 5 | 0 |
+---------+---------+---------+----------+
1 row in set (0.00 sec)
mysql> select 1<<2,2<<2,10>>2,15>>4;
+------+------+-------+-------+
| 1<<2 | 2<<2 | 10>>2 | 15>>4 |
+------+------+-------+-------+
| 4 | 8 | 2 | 0 |
+------+------+-------+-------+
1 row in set (0.00 sec)
(5)运算符优先级
【10】连接查询
MySQL 的连接查询,通常都是将来自两个或多个表的行结合起来,基于这些表之间的共同字段,进行数据的拼接。首先,要确定一个主表作为结果集,然后将其他表的行有选择 性的连接到选定的主表结果集上。使用较多的连接查询包括:内连接、左连接和右连接。
//查看student1表的信息
mysql> select * from student1;
+----+----------+--------+--------+
| id | name | socre | course |
+----+----------+--------+--------+
| 1 | lisi | 104.00 | 1 |
| 2 | zhangsan | 93.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 |
| 5 | tianbi | 66.00 | 3 |
+----+----------+--------+--------+
5 rows in set (0.00 sec)
//查看student表的信息
mysql> select * from student;
+----+----------+--------+--------+
| id | name | socre | course |
+----+----------+--------+--------+
| 1 | lisi | 104.00 | 1 |
| 2 | zhangsan | 93.00 | 1 |
| 3 | tianqi | 77.00 | 2 |
| 4 | long | 120.00 | 3 |
| 5 | zhuge | 20.00 | 2 |
+----+----------+--------+--------+
5 rows in set (0.00 sec)
//查询course表的信息
mysql> select * from course;
+----+--------+---------+
| id | name | teacher |
+----+--------+---------+
| 1 | 语文 | yangqi |
| 2 | 数学 | yangba |
| 3 | 英语 | yangjiu |
+----+--------+---------+
3 rows in set (0.00 sec)
(1)内连接
MySQL 中的内连接就是两张或多张表中同时符合某种条件的数据记录的组合。通常在FROM 子句中使用关键字 INNER JOIN 来连接多张表,并使用 ON 子句设置连接条件。内连接是系统默认的表连接,所以在 FROM 子句后可以省略 INNER 关键字,只使用关键字 JOIN。同时有多个表时,也可以连续使用 INNER JOIN 来实现多表的内连接,不过为了更好的性能,建议最好不要超过三个表。
格式一:连接两表关系查询
SELECT 字段 FROM 表1 INNER JOIN 表2 ON 表1.外键 =表2.主键;
格式二:显示两表相同内容
SELECT 字段 FROM 表1 INNER JOIN 表2 ON 字段关系;
如果表中至少有一个匹配项,INNER JOIN 关键字将返回一行。如果没有匹配项,则不会有输出结果。
格式一举例:
mysql> select student1.name,socre,course,course.name,teacher from student1
inner join courrse on student1.course=course.id;
+----------+--------+--------+--------+---------+
| name | socre | course | name | teacher |
+----------+--------+--------+--------+---------+
| lisi | 104.00 | 1 | 语文 | yangqi |
| zhangsan | 93.00 | 1 | 语文 | yangqi |
| tianqi | 77.00 | 2 | 数学 | yangba |
| qianba | 78.00 | 3 | 英语 | yangjiu |
| tianbi | 66.00 | 3 | 英语 | yangjiu |
+----------+--------+--------+--------+---------+
5 rows in set (0.00 sec)
格式二举例:
//只查询相同的部分
mysql> select * from student1 inner join student on student1.name=student.name;
+----+----------+--------+--------+----+----------+--------+--------+
| id | name | socre | course | id | name | socre | course |
+----+----------+--------+--------+----+----------+--------+--------+
| 1 | lisi | 104.00 | 1 | 1 | lisi | 104.00 | 1 |
| 2 | zhangsan | 93.00 | 1 | 2 | zhangsan | 93.00 | 1 |
| 3 | tianqi | 77.00 | 2 | 3 | tianqi | 77.00 | 2 |
+----+----------+--------+--------+----+----------+--------+--------+
3 rows in set (0.00 sec)
(2)外连接之左连接
MySQL 除了内连接,还可以使用外连接。区别于 MySQL 外连接是将表分为基础表和参考表,再依据基础表返回满足条件或不满足条件的记录。外连接按照连接时表的顺序来分, 有左连接和右连接之分。左连接也可以被称为左外连接,在 FROM 子句中使用 LEFT JOIN 或者 LEFT OUTER JOIN 关键字来表示。左连接以左侧表为基础表,接收左表的所有行,并用这些行与右侧参考表中的记录进行匹配,也就是说匹配左表中的所有行以及右表中符合条件的行。
格式:
select * from 表1 left join 表2 on 字段关系;
从原理图可以看出,左连接中左表的记录将会全部表示出来,而右表只会显示符合搜索 条件的记录,也就是图中交叉的部分。右表记录不足的地方均为 NULL。
//左侧表全部显示,右侧表显示相同部分,不同部分显示null值
mysql> select * from student1 left join student on student1.name=student.name;
+----+----------+--------+--------+------+----------+--------+--------+
| id | name | socre | course | id | name | socre | course |
+----+----------+--------+--------+------+----------+--------+--------+
| 1 | lisi | 104.00 | 1 | 1 | lisi | 104.00 | 1 |
| 2 | zhangsan | 93.00 | 1 | 2 | zhangsan | 93.00 | 1 |
| 3 | tianqi | 77.00 | 2 | 3 | tianqi | 77.00 | 2 |
| 4 | qianba | 78.00 | 3 | NULL | NULL | NULL | NULL |
| 5 | tianbi | 66.00 | 3 | NULL | NULL | NULL | NULL |
+----+----------+--------+--------+------+----------+--------+--------+
5 rows in set (0.00 sec)
(3)外连接之右连接
右连接也被称为右外连接,在 FROM 子句中使用 RIGHT JOIN 或者 RIGHT OUTER JOIN 关键字来表示。右连接跟左连接正好相反,它是以右表为基础表,用于接收右表中的所有行,并用这些记录与左表中的行进行匹配。也就是说匹配右表中的每一行及左表中符合条件的记录。
格式:
select * from 表1 right join b_player 表2 on 字段关系;
在右连接的查询结果集中,除了符合匹配规则的行外,还包括右表中有但是左表中不匹 配的行,这些记录在左表中以 NULL 补足。
//右侧部分全部显示,左侧部分只显示相同部分,不同部分显示null值
mysql> select * from student1 right join student on student1.name=student.name;
+------+----------+--------+--------+----+----------+--------+--------+
| id | name | socre | course | id | name | socre | course |
+------+----------+--------+--------+----+----------+--------+--------+
| 1 | lisi | 104.00 | 1 | 1 | lisi | 104.00 | 1 |
| 2 | zhangsan | 93.00 | 1 | 2 | zhangsan | 93.00 | 1 |
| 3 | tianqi | 77.00 | 2 | 3 | tianqi | 77.00 | 2 |
| NULL | NULL | NULL | NULL | 4 | long | 120.00 | 3 |
| NULL | NULL | NULL | NULL | 5 | zhuge | 20.00 | 2 |
+------+----------+--------+--------+----+----------+--------+--------+
5 rows in set (0.00 sec)