mysql基础(2)查询

 七、数据表的查询

查询语法如下:

SELECT
[ DISTINCT ] {* | {column [, column ] ...}
[ FROM table_name ]
[ WHERE ...]
[ ORDER BY column [ ASC | DESC ], ...]
LIMIT ...

实例:

-- 创建考试成绩表
DROP TABLE IF EXISTS exam_result;
CREATE TABLE exam_result (
 id INT,
 name VARCHAR(20),
 chinese DECIMAL(3,1),
 math DECIMAL(3,1),
 english DECIMAL(3,1)
);
-- 插入测试数据
INSERT INTO exam_result (id,name, chinese, math, english) VALUES
 (1,'唐三藏', 67, 98, 56),
 (2,'孙悟空', 87.5, 78, 77),
 (3,'猪悟能', 88, 98.5, 90),
 (4,'曹孟德', 82, 84, 67),
 (5,'刘玄德', 55.5, 85, 45),
 (6,'孙权', 70, 73, 78.5),
 (7,'宋公明', 75, 65, 30);

1、全列查询

select * from exam_result;

2、指定列查询

-- 指定列的顺序不需要按定义表的顺序来
SELECT id, name, english FROM exam_result;

3、查询字段为表达式

-- 表达式不包含字段
SELECT id, name, 10 FROM exam_result;
-- 表达式包含一个字段
SELECT id, name, english + 10 FROM exam_result;
-- 表达式包含多个字段
SELECT id, name, chinese + math + english FROM exam_result;

select math from exam_result;

4、别名

为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称,语法:

SELECT column [ AS ] alias_name [...] FROM table_name;
-- 结果集中,表头的列名=别名
SELECT id, name, chinese + math + english 总分 FROM exam_result;

5、去重DISTINCT

使用 DISTINCT 关键字对某列数据进行去重.

查询math列,可见98分重复了:

select math from exam_result;

使用DISTINCT进行去重,去重结果:

select distinct math from exam_result;

6、排序ORDER BY

语法:

-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [ WHERE ...]
ORDER BY column [ ASC | DESC ], [...];
  • 没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序
  • NULL 数据排序,视为比任何值都小,升序出现在最上面,降序出现在最下面 (MySQL中默认排序为升序)

1、升序和降序

-- 查询同学姓名和 qq_mail,按 qq_mail 排序显示
-- 升序
SELECT name, qq_mail FROM student ORDER BY qq_mail;
-- 降序
SELECT name, qq_mail FROM student  ORDER BY qq_mail DESC;

2、使用 表达式 及 别名 排序

-- 查询同学及总分,由高到低
SELECT name, chinese + english + math FROM exam_result
ORDER BY chinese + english + math DESC;
SELECT name, chinese + english + math total FROM exam_result
ORDER BY total DESC; 

3、可以对多个字段进行排序,排序优先级随书写顺序

-- 查询同学各门成绩,按数学降序,英语升序,语文升序的方式进行排序
select name,math,english,chinese from exam_result order by math desc,english,chinese;

7、分组GROUP BY

GROUP BY 是一种能将查询结果划分为多个行组的查询语句的子句,其目的通常是为了在每个组上执行一个或多个聚合运算,所以 GROUP BY 通常会与聚合函数一块儿出现在查询语句中。

GROUP BY 的标准分组方式是按所有分组字段的值依次来分组。假如字段 A 的值有 3 种,字段 B 的值有 2 种;如果是GROUP BY A,那么就会被分为 3 组;而如果是GROUP BY A,B,那么就会先被 A 分为 3 组,然后这 3 组又会被 B 再各自分为 2 组,最终会被分为 3×2 等于 6 组。

显然,GROUP BY B,A最终也会被分为 6 组,换而言之,标准分组时的字段的顺序不会对分组结果产生影响。但分组字段的顺序会影响查询结果的排序,如果想要改变结果集的排序,可以通过 ORDER BY 子句来实现。

--分组group by
select num from 表 group by num
select num,nid from 表 group by num,nid
select num,nid from 表  where nid > 10 group by num,nid order nid desc
select num,nid,count(*),sum(score),max(score),min(score) from 表 group by num,nid
select num from 表 group by num having max(id) > 10	
select 
	fieldName as alias,
	fieldName as alias,
	(fieldName + fieldName) as alias
from
	表名列表
where
	条件列表
group by
	分组字段
having 
	分组之后的条件
order by
	fieldName desc 
limit
	分页限定

1、GROUP BY 与聚合函数

示例一、查询统计学生 1、2、3 的第 1 次考试成绩,且按各科总分降序排列:
SELECT t.StudentId,COUNT(1) 科目数,
    SUM(t.Scores) 总分,MAX(t.Scores) 最高分,MIN(t.Scores) 最低分,AVG(t.Scores) 平均分 
FROM T_ExamResults t 
WHERE t.Counts = 1 AND t.StudentId IN(1,2,3) 
GROUP BY t.StudentId 
ORDER BY 总分 DESC;

注意:在含有 GROUP BY 子句的查询语句中,每组只会返回一行数据,且查询选择列表中的列只能是 GROUP BY 中的字段或聚合函数表达式。

2、GROUP BY 与 HAVING

HAVING 子句的作用有点类似于 WHERE 子句,说到底它们都是过滤数据用的,但不同的是,WHERE 子句过滤的最小单位是数据行,而 HAVING 子句过滤的最小单位是行组。相较于 WHERE 子句,HAVING 子句最大的优势就是支持聚合函数。

HAVING 子句只能在查询语句中使用,且通常与 GROUP BY 子句一起使用。如果查询语句中没有 GROUP BY 子句,那么就会有隐式的单一行组,但这通常是没有意义的。例如要查询统计平均分达到 80 分的学生第 1 次考试成绩,且按总分倒序排列,示例如下:

SELECT t.StudentId,COUNT(1) 科目数,
    SUM(t.Scores) 总分,MAX(t.Scores) 最高分,MIN(t.Scores) 最低分,AVG(t.Scores) 平均分 
FROM T_ExamResults t 
WHERE t.Counts = 1 
GROUP BY t.StudentId 
HAVING AVG(t.Scores) >= 80
ORDER BY SUM(t.Scores) DESC;

8、条件查询:WHERE

  • WHERE 条件可以使用表达式,但不能使用别名。
  • AND 的优先级高于 OR ,在同时使用时,需要使用小括号 () 包裹优先执行的部分

1.基本查询:

-- 1、查询英语不及格的同学及英语成绩 ( < 60 )
SELECT name, english FROM exam_result WHERE english < 60; 

-- 2、查询语文成绩好于英语成绩的同学
SELECT name, chinese, english FROM exam_result WHERE chinese > english; 

-- 3、查询总分在 200 分以下的同学
SELECT name, chinese + math + english 总分 FROM exam_result
WHERE chinese + math + english < 200; 

2、AND与OR:

-- 查询语文成绩大于 80 分,且英语成绩大于 80 分的同学
SELECT * FROM exam_result WHERE chinese > 80 and english > 80;

-- 查询语文成绩大于 80 分,或英语成绩大于 80 分的同学
SELECT * FROM exam_result WHERE chinese > 80 or english > 80; 

-- 观察 AND 和 OR 的优先级:
SELECT * FROM exam_result WHERE chinese > 80 or math>70 and english > 70;
SELECT * FROM exam_result WHERE (chinese > 80 or math>70) and english > 70; 

3、BETWEEN ... AND ...

-- 查询语文成绩在 [80, 90] 分的同学及语文成绩
SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90; 

-- 使用 AND 也可以实现
SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese
<= 90; 

4、IN

-- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99); 

-- 使用 OR 也可以实现
SELECT name, math FROM exam_result WHERE math = 58 OR math = 59 OR math
= 98 OR math = 99;

5、模糊查询:LIKE

-- % 匹配任意多个(包括 0 个)字符
SELECT name FROM exam_result WHERE name LIKE '孙%';-- 匹配到孙悟空、孙权 


-- _ 匹配严格的一个任意字符
SELECT name FROM exam_result WHERE name LIKE '孙_';-- 匹配到孙权 

6、NULL 的查询:IS [NOT] NULL

-- 查询 qq_mail 已知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NOT NULL; 

-- 查询 qq_mail 未知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NULL;

7、分页查询:LIMIT

语法:

-- 起始下标为 0
-- 从 0 开始,筛选 n 条结果
SELECT ... FROM table_name [ WHERE ...] [ ORDER BY ...] LIMIT n;
-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [ WHERE ...] [ ORDER BY ...] LIMIT s, n;
-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT ... FROM table_name [ WHERE ...] [ ORDER BY ...] LIMIT n OFFSET s;

案例:按 id 进行分页,每页 3 条记录,分别显示 第 1 、 2 、 3 页

-- 第 1 页
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 0; 

-- 第 2 页
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 3; 

-- 第 3 页,如果结果不足 3 个,不会有影响
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 6; 

8、聚合查询

8.1 聚合函数

聚合函数查询又叫函数查询,它是通过一些特定的函数根据需求来查询相关的信息,常见的聚合函数为:

        COUNT - 求总数,不包含某字段为null值
        SUM - 求和,不包含某字段为null值
        AVG - 求平均值,不包含某字段为null值
        MAX - 求最大值,适用于数值、日期、字符串类型,不包含某字段为null值
        MIN - 求最小值,适用于数值、日期、字符串类型,不包含某字段为null值
聚合函数的使用是在select语句中实现的,

因此它的语法为:select 聚合函数(字段) from 表名;

首先我们创建一个名为test的数据库:

//创建一个名为test的数据库
mysql> create database test charset utf8;
Query OK, 1 row affected (0.00 sec)
 
//使用test数据库
mysql> use test;
Database changed

创建数据库后,我们得通过use指令来使用这个数据库,这样我们在创建表和对表进行操作时数据的来源都是在这个数据库中。

创建一个名为score的课程表: 

//创建一个课程表score
mysql> create table score(
    -> id int,
    -> name varchar(20),
    -> chinese int,
    -> math int,
    -> english int);
Query OK, 0 rows affected (0.02 sec)
//插入四行数据
mysql> insert into score(id,name,chinese,math,english) values
    -> (1,'张三',77,89,56),
    -> (2,'李四',85,98,32),
    -> (3,'王五',67,75,64),
    -> (4,'赵六',98,93,88);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
8.1.1 count函数

count函数我们不难理解,它是用来计数的一个函数。通常用来记录一个表中的某字段出现的次数。

count函数是用来计数的,统计某一个字段出现的次数,语法:select count(字段) from 表名;

如使用count函数通过id计算总人数:

mysql> select count(id) from score;
+-----------+
| count(id) |
+-----------+
|         4 |
+-----------+
1 row in set (0.01 sec)

通过上述代码,我们可以看到通过count这个函数可以计算到了score表中id字段的总数。注意这里的总数是字段总个数,如果某一行为null则不列入计数总数当中。

8.1.2 sum函数

sum函数,是用来计算总和的函数。如使用sum函数计算score表中chinese成绩的总数:

mysql> select sum(chinese) from score;
+--------------+
| sum(chinese) |
+--------------+
|          327 |
+--------------+
1 row in set (0.00 sec)

我们可以看到,使用sum函数可以很好的求道某一个字段的总和。当然在函数的后面也可以加上别名,如给sum(chinese)起别名位total:

mysql> select sum(chinese) as total from score;
+-------+
| total |
+-------+
|   327 |
+-------+
1 row in set (0.00 sec)

通过上述代码我们可以知道,聚合函数的后面是可以起别名的,起别名是通过as这个关键字来起的。其中as可以省略,但建议加上该关键字这样代码的可读性较高一些。

8.1.3 avg函数

avg函数是用来求某一字段的平均值,如使用avg函数求english的平均值:

mysql> select avg(english) from score;
+--------------+
| avg(english) |
+--------------+
|      60.0000 |
+--------------+
1 row in set (0.00 sec)

通过上述代码我们可以看到,avg得到的结果默认保留了4位小数,那我们想要avg保留相应的小数可以这样做:

mysql> select round(avg(english),2) as avg from score;
+-------+
| avg   |
+-------+
| 60.00 |
+-------+
1 row in set (0.00 sec)

使用round函数,使得avg的结果保留相应的小数位。在上述程序中,我保留的是2位小数,大家可以根据需求自行设计。

round函数是用来做四舍五入操作的,当然你可以规定保留几位小数。

        语法为:select 字段 round(字段,保留位数) from 表名;

8.1.4 max函数

max函数是求得的是某一字段的最大值,如使用max函数求得math成绩的最大值:

mysql> select max(math) from score;
+-----------+
| max(math) |
+-----------+
|        98 |
+-----------+
1 row in set (0.00 sec)

我们可以看到,math字段的最大值98被查询出来了,max函数的用法也是很简单。

8.1.5min函数

通过上方讲解我们知道了max函数是求最大值的,那么min函数是求得某一字段的最小值,如使用min函数求得english成绩的最小值:

mysql> select min(english) from score;
+--------------+
| min(english) |
+--------------+
|           32 |
+--------------+
1 row in set (0.00 sec)

通过上述代码可以看到,english字段的最小值32被查找出来了,min函数的使用方法也是比的简单

8.2 分组函数的注意事项:

首先,我们创建一个简易的薪资表,往后的所有函数也是通过这张表来讲解。

mysql> create table Pay(
    -> id int,
    -> name varchar(10),
    -> salary decimal(10,3),
    -> bonus decimal(10,3),
    -> holiday int
    -> );
Query OK, 0 rows affected (0.02 sec)
 
mysql> insert into Pay (id,name,salary,bonus,holiday) values
    -> (1001,'Bob',2345.435,800,5),
    -> (1002,'Tom',3454.534,500.435,2),
    -> (1003,'Mimi',5534.565,900,10),
    -> (1004,'Boss',10000,888.666,20);
    -> (1005,'Ggg',2454,300,null);
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0
 
mysql> select * from Pay;
+------+------+-----------+---------+---------+
| id   | name | salary    | bonus   | holiday |
+------+------+-----------+---------+---------+
| 1001 | Bob  |  2345.435 | 800.000 |       5 |
| 1002 | Tom  |  3454.534 | 500.435 |       2 |
| 1003 | Mimi |  5534.565 | 900.000 |      10 |
| 1004 | Boss | 10000.000 | 888.666 |      20 |
| 1005 | Ggg  |  2454.000 | 300.000 |    NULL |
+------+------+-----------+---------+---------+
5 rows in set (0.00 sec)
8.2.1  注意1

在mysql数据库中,在运算时如果某一数据为NULL。则最后的结果一定是空,但在分组函数进行运算时会自动忽略NULL。

select * from Pay;

我们可以看到Pay表中假期(holiday)字段有一空,那么我对它进行求和会不会造成结果为空呢?

mysql> select sum(holiday) test from Pay;
+------+
| test |
+------+
|   37 |
+------+
1 row in set (0.00 sec)

我们发现并没有结果为NULL,证实了上面那句话,分组函数运算时忽略NULL。

8.2.1  注意2

分组函数中的count(*)和count(某字段)有什么区别?

count(*)是统计该字段所有数据的计数包括NULL,而count(字段)是统计除NULL以外数据的计数。

mysql> select count(*) from Pay;
+----------+
| count(*) |
+----------+
|        5 |
+----------+
1 row in set (0.00 sec)
 
mysql> select count(holiday) from Pay;
+----------------+
| count(holiday) |
+----------------+
|              4 |
+----------------+
1 row in set (0.00 sec)

 因此,count(*)是通常是用来统计行数的,count(字段)是用来计数某一字段除NULL以外的数据。

8.2.3 注意3

分组函数不得直接使用在where子句中!会提示使用了无效的分组函数 。

如用条件查询找工资最大值:

mysql> select name,salary salmax from Pay where salary>min(salary);
ERROR 1111 (HY000): Invalid use of group function

8.2.4 注意4

分组函数可以联合使用,比如我要将员工薪资的最小值,最大值,平均值,总和,员工个数显示出来: 

mysql> select min(salary) salmin,max(salary) salmax,avg(salary) salavg,sum(salary) salsum,count(*) salcou from Pay;
+----------+-----------+--------------+-----------+--------+
| salmin   | salmax    | salavg       | salsum    | salcou |
+----------+-----------+--------------+-----------+--------+
| 2345.435 | 10000.000 | 4757.7068000 | 23788.534 |      5 |
+----------+-----------+--------------+-----------+--------+
1 row in set (0.00 sec)

9、连接查询

  在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。一个业务都会对应多张表,比如:学生和班级,起码两张表。(避免产生数据的冗余)。

内连接和外连接的区别

       1、内连接:

        假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。AB两张表没有主副之分,两张表是平等的。

        2、外连接:

        假设A和B表进行连接,使用外连接的话, AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表。当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

9.1 连接查询的分类

  • 交叉连接:笛卡尔积。
  • 内连接:等值连接、非等值连接、自连接。(还可分为隐式【无join】和显式【有join】)
  • 外连接:左外连接(左连接)、右外连接(右连接)、全连接。

生成测试数据

执行下面的sql语句生成student表和teacher表,两表通过teacher_id关联。

create table student(
    id int(3) not null primary key,
    name char(6) not null,
    age int(2) not null,
    teacher_id int(3) not null
);
create table teacher(
    id int(3) not null primary key,
    name char(6) not null,
    age int(2) not null,
    class_id int(3) not null
);
插入值 id 姓名 年龄 教师id
 
insert into student values(1, '刘峰', 20, 1);
insert into student values(2, '李福', 22, 2);
insert into student values(3, '王紫', 21, 3);
insert into student values(4, '赵兰', 24, 4);
insert into student values(5, '夏日', 23, 5);
insert into student values(6, '詹启', 22, 6);
insert into student values(7, '刘娜', 24, 4);
insert into student values(8, '王恒', 23, 5);
insert into student values(9, '晓飞', 22, 6);
 
插入值 id 姓名 年龄 班级id
 
insert into teacher values(1, '夏晴', 36, 1);
insert into teacher values(2, '李淳', 32, 2);
insert into teacher values(3, '张叶', 34, 3);
insert into teacher values(4, '鹿雪', 37, 3);
insert into teacher values(5, '刘花', 36, 2);
insert into teacher values(6, '贾义', 34, 1);

执行下面查询语句,student表和teacher表如下:
 

 
select * from student;
select * from teacher;

9.2 七种常用连接查询详解 

9.2.1 笛卡尔积

  笛卡尔积也称交叉连接,交叉连接是内连接的一种。

 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。如果A表示某学校学生的集合,B表示该学校所有教师的集合,则A与B的笛卡尔积表示学生选择老师所有可能的情况。

      笛卡尔积特点:它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行 一 一 匹配。

      重点记:

      笛卡尔积:用的比较少,因为存在重复数据
      笛卡尔积:一个表的每条数据都和另一个表的所有数据匹配一次
      结       果: 一表 9 条 乘以 另一表 6 条 = 54 条

案例如下:

     查询学生对应的老师

     

select * from student ,teacher;

     学生表 中数据每 1 个学生都和 教师表 中的 所有教师 都匹配一次。

问题:
       当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。这就是笛卡尔积现象。 查询出来的结果是两张表的记录的乘积 9*6=54,许多数据是无效数据。如何避免笛卡尔积现象?

 解决方案: 

        增加加条件进行过滤,但只会显示有效记录。此时也是隐式(无join)内连接

根据教师id查询学生对应的选课老师
       

 select st.*,th.* from student st ,teacher th where st.teacher_id = th.id;

注意:使用as可以对表和字段起别名,关于表的别名的优点:执行效率高;可读性好。
                 其中st是student的表的别名,原是from student as st,其中as可以省略。
                 其中th是teacher的表的别名,原是from teacher as th,其中as可以省略。

9.2.2 内连接

内连接,取的就是两张表的交集。

 内连接又分为等值连接、非等值连接、自连接。(还可分为隐式【无join】和显式【有join】)

9.2.2.1 隐式与显式连接

(1)隐式(无join)连接语法:

select 字段 from 表A, 表B​ where 消除笛卡尔积的连接条件

案例:根据教师id查询学生对应的选课老师

select st.*,th.* from student st ,teacher th where st.teacher_id = th.id;

(2)显式(有join)连接语法

   select 字段* from 表A 别名 INNER(可以省略) JOIN 表B 别名 ON 消除笛卡尔积的连接条件

      案例:根据教师id查询学生对应的选课老师

     

select st.*,th.* from student st inner join teacher th on st.teacher_id = th.id;

     

select st.*,th.* from student st join teacher th on st.teacher_id = th.id;#(inner 可以省略)

9.2.2.2 等值连接

等值连接的最大的特点就是:条件是等量关系(最常用)。

 等值连接语法
     select 字段* from 表1  INNER(可以省略) JOIN 表2  ON 消除笛卡尔积的连接条件A=B

  案例:根据教师id查询学生对应的选课老师

 select st.*,th.* from student st join teacher th on st.teacher_id = th.id;

9.2.2.3 非等值连接

非等值连接的最大的特点就是:条件不是是等量关系

非等值连接语法
     select 字段* from 表1  INNER(可以省略) JOIN 表2  ON 消除笛卡尔积的连接条件

案例:查询教师id在4-6之间所教的学生和老师信息

SELECT st.*, th.*
FROM student st
JOIN teacher th ON st.teacher_id = th.id AND (th.id BETWEEN 4 AND 6);

 9.2.3 外连接 

外连接又分为左外连接、右外连接、全连接

    左外连接(LEFT OUTER JOIN),简称左连接(LEFT JOIN)

    右外连接(RIGHT OUTER JOIN),简称右连接(RIGHT JOIN)

    全外连接(FULL OUTER JOIN),简称全连接(FULL JOIN)

-- 向 student 表 中插入两条语句,teacher_id的 13 和 15 在teacher中是不存在的。
INSERT INTO `student`(`id`, `name`, `age`, `teacher_id`) VALUES (10, '夏雨', 21,13);
INSERT INTO `student`(`id`, `name`, `age`, `teacher_id`) VALUES (11, '冬雪', 22,15);

--插入 teacher 表 三条语句,id分别为
INSERT INTO `teacher`(`id`, `name`, `age`, `class_id`) VALUES (7, '付霞', 34, 4);
INSERT INTO `teacher`(`id`, `name`, `age`, `class_id`) VALUES (8, '郝仁', 33, 5);
INSERT INTO `teacher`(`id`, `name`, `age`, `class_id`) VALUES (9, '赵刚', 35, 7);
9.2.3.1左外连接:

  • 左外连接:left join 或 left outrer join  (outer可以省略)
  •  左外连接:左边的是主表,左表数据全部显示,右表显示符合ON后的条件的数据,不符合的用NULL代替。

    select * from student st left join teacher th on st.teacher_id = th.id;(outer可以省略)

    通过查询结果发现,左外连接查询的是 左表独有的数据 加上 两表共有的数据

  •  左外特殊情况:返回没有匹配的记录

案例:查询没有教师的学生信息

      

select * from student st left join teacher th on st.teacher_id = th.id where th.id is null;

 9.2.3.2右外连接:
  •  右外连接:right join 或 right outrer join  (outer可以省略)
  • 右外连接:右边边的是主表,右边表数据全部显示,左边表显示符合ON后的条件的数据,不符合的用NULL代替。

 select * from student st right join teacher th on st.teacher_id = th.id;(outer可以省略)

 通过结果发现,右外连接查询的是 右表独有的数据 加上 两表共有的数据

右外特殊情况:返回没有匹配的记录

案例:查询没有学生的教师信息

       

select * from student st right join teacher th on st.teacher_id = th.id where st.teacher_id is null;

  通过查询发现,右连接查询的为右表独有的数据。

9.2.3.3全外连接

全外连接:full join 或 full outer join(outer可以省略),但Mysql不支持,可以使用union组合并去重实现。 
      简单理解:全外接查询:就是 左表独有的数据 加上 右表独有的数据

select * from student st left join teacher th on st.teacher_id = th.id where th.id is null
union 
select * from student st right join teacher th on st.teacher_id = th.id where st.teacher_id is null

9.3 3.4全连接

全连接:full join 或 full outer join(outer可以省略),但Mysql不支持,可以使用union组合并去重实现。

       简单理解:全连接查询的是 左表所有的数据  加上 右表所有的数据 并去重。 

select * from student st left join teacher th on st.teacher_id = th.id
union 
select * from student st right join teacher th on st.teacher_id = th.id

       

总结:mysql存在七种连接,分别是内连接、左外连接、左外连接特殊情况、右外连接、右外连接特殊情况、全连接、全外连接。总结在一起就是内连接、左外连接、右外连接、全外连接。

  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石明亮(JT)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值