数据库--数据库约束/聚合查询/分组查询/联合查询

       前言 

        逆水行舟,不进则退!!!     


目录

       数据库约束       

       聚合查询

       分组查询 

       联合查询 

       联合查询---内连接与外连接

       补充

       联合查询用到的代码


       数据库约束       

not null 约束:在创建表的时候,可以指定列插入的值不允许为null ;

语法:例:create table student (id int not null, name varchar(20) not null);

数据库--数据库约束/聚合查询/分组查询/联合查询_第1张图片

   


unique 约束:插入或修改 数据的时候,会先查询要 插入或修改 的数据是否已经存在,如果不存在,则可以 插入或修改;如果存在,则插入或修改失败;

语法:例:create table student (id int unique, name varchar(20));

数据库--数据库约束/聚合查询/分组查询/联合查询_第2张图片


default 约束:设置默认值,默认值是insert指定列插入的时候,其他未被指定的列就是按照默认值来填充的。

  语法:例:create table student (id int, name varchar(20) default '无名氏');

数据库--数据库约束/聚合查询/分组查询/联合查询_第3张图片

        


primary key 约束:设置主键值作为约束,在mysql中,要求一个表中,只能有一个主键。在创建主键的时候,可以使用一个列作为主键,也可以使用多个列作为主键(复合主键)。

        数据库中的主键是一种用于唯一标识表中每一行数据的字段或一组字段。主键的作用是确保表中每一行数据都有一个唯一的标识符,以便于在表中进行数据的查找、更新和删除等操作。主键还可以用于建立表之间的关系,例如在关系型数据库中,可以通过主键和外键来建立表与表之间的关联关系。

       主键所在的列不能为null,不能有重复,相当于同时加上了not null 约束 和 unique 约束。

语法:例:create table student (id int primary key, name varchar(20));

数据库--数据库约束/聚合查询/分组查询/联合查询_第4张图片

自增主键:  比普通主键多了一个要求,要求指定列必须是整数。

语法:create table student (id int primary key auto_increment, name varchar(20));

数据库--数据库约束/聚合查询/分组查询/联合查询_第5张图片

                

                        如果插入数据的时候,不指定主键,数据表会根据主键的值进行自动填充。但是需要注意一点,自增主键会根据主键的最大值进行自增填充。

数据库--数据库约束/聚合查询/分组查询/联合查询_第6张图片

数据库--数据库约束/聚合查询/分组查询/联合查询_第7张图片


foreign key 外键约束:用于在两个表之间建立链接。其中一个表的一个字段被另一个表中对应的字段所约束。被约束的表称为从表(子表),另一个表称为主表(父表)。外键约束可以确保数据的完整性和一致性,防止出现不一致的数据。

建立约束:先创建从表,然后再创建主表时,在字段后加上 foreign key (主表中列名) references 从表名(从表中要关联的列名) ;

数据库--数据库约束/聚合查询/分组查询/联合查询_第8张图片

验证约束:

数据库--数据库约束/聚合查询/分组查询/联合查询_第9张图片

约束是相互的。主表对从表有约束,同样的,从表对主表也有约束。

数据库--数据库约束/聚合查询/分组查询/联合查询_第10张图片


       聚合查询

        查询过程中,把表的行和行之间进行一定的运算。这个过程是依赖于一些聚合函数,也就是SQL提供的库函数

函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的 数量
SUM([DISTINCT] expr) 返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr) 返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的 最小值,不是数字没有意义

现有如下数据:我们将对这些数据进行演示。

select * from exam_result;
+------+--------------+---------+------+---------+
| id   | name         | chinese | math | english |
+------+--------------+---------+------+---------+
|    1 | 唐三藏       |    67.0 | 98.0 |    56.0 |
|    2 | 孙悟空       |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能       |    88.0 | 98.5 |    90.0 |
|    4 | 曹孟德       |    82.0 | 84.0 |    67.0 |
|    5 | 刘玄德       |    55.5 | 85.0 |    45.0 |
|    6 | 孙权         |    70.0 | 73.0 |    78.5 |
|    7 | 宋公明       |    75.0 | 65.0 |    30.0 |
|    8 | 如来佛祖     |    NULL | NULL |    NULL |
+------+--------------+---------+------+---------+
8 rows in set (0.00 sec)

count:返回查询到的数据的 数量

语法:select count(列名) from 表名

 全列查询:select count(*) from exam_result;

select count(*) from exam_result;
+----------+
| count(*) |
+----------+
|        8 |
+----------+
1 row in set (0.00 sec)

 单列查询:select count(列名) from exam_result;

select count(name) from exam_result;
+-------------+
| count(name) |
+-------------+
|           8 |
+-------------+
1 row in set (0.00 sec)
select count(chinese) from exam_result;
+----------------+
| count(chinese) |
+----------------+
|              7 |
+----------------+
1 row in set (0.00 sec)

        从上面代码,我们发现,在对某一列进行 count 查询时,如果某行的值为NULL,则该行不计入总个数中。

        注:count等聚合函数 与 () 中间不能有空格。 

sum:返回查询到的数据的 总和,不是数字没有意义

语法:select sum(列名) from exam_result;

select sum(chinese) from exam_result;
+--------------+
| sum(chinese) |
+--------------+
|        525.0 |
+--------------+
1 row in set (0.03 sec)

        在学sql的四则表达式时,我们说过,如果表达式中含有null,则表达式的结果为null;但若是聚合函数碰到了NULL值,则会直接跳过。

        当使用sum对字符串进行操作时,会有什么结果?

select sum(name) from exam_result;
+-----------+
| sum(name) |
+-----------+
|         0 |
+-----------+
1 row in set, 8 warnings (0.00 sec)
//可以看到,这里报了8个warning


show warnings;
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '唐三藏'       |
| Warning | 1292 | Truncated incorrect DOUBLE value: '孙悟空'       |
| Warning | 1292 | Truncated incorrect DOUBLE value: '猪悟能'       |
| Warning | 1292 | Truncated incorrect DOUBLE value: '曹孟德'       |
| Warning | 1292 | Truncated incorrect DOUBLE value: '刘玄德'       |
| Warning | 1292 | Truncated incorrect DOUBLE value: '孙权'         |
| Warning | 1292 | Truncated incorrect DOUBLE value: '宋公明'       |
| Warning | 1292 | Truncated incorrect DOUBLE value: '如来佛祖'     |
+---------+------+--------------------------------------------------+
8 rows in set (0.00 sec)

        其实不只是sum,其他只针对数字的聚合函数在对字符串进行操作的时候也都会报警告。

avg:返回查询到的数据的 平均值,不是数字没有意义

语法:select avg(列名) from exam_result;

select avg(chinese) from exam_result;
+--------------+
| avg(chinese) |
+--------------+
|     75.00000 |
+--------------+
1 row in set (0.03 sec)

        聚合函数还能搭配表达式使用。如求总分的平均分。

select avg(chinese + math + english) as avg_total from exam_result;
+-----------+
| avg_total |
+-----------+
| 221.42857 |
+-----------+
1 row in set (0.00 sec)

max:返回查询到的数据的 最大值,不是数字没有意义

min:返回查询到的数据的 最小值,不是数字没有意义

select max(chinese), min(chinese) from exam_result;
+--------------+--------------+
| max(chinese) | min(chinese) |
+--------------+--------------+
|         88.0 |         55.5 |
+--------------+--------------+
1 row in set (0.00 sec)


       分组查询 

        关键字 :group by

        分组查询常常和聚合查询搭配进行查询。

现有如下数据:

select * from emp;
+------+--------------+-----------+--------+
| id   | name         | role      | salary |
+------+--------------+-----------+--------+
|    1 | 孙悟空       | 讲师      |  10000 |
|    2 | 猪悟能       | 讲师      |  11000 |
|    3 | 沙悟净       | 讲师      |  12000 |
|    4 | 刘玄德       | 学管师    |  10000 |
|    5 | 曹孟德       | 学管师    |   9000 |
|    6 | 如来佛祖     | 老板      | 100000 |
|    7 | 太上老君     | 老板      | 120000 |
+------+--------------+-----------+--------+
7 rows in set (0.00 sec)

针对岗位进行分组查询平均薪资,执行结果如下:

select role, avg(salary) from emp group by role;
+-----------+-------------+
| role      | avg(salary) |
+-----------+-------------+
| 学管师    |   9500.0000 |
| 老板      | 110000.0000 |
| 讲师      |  11000.0000 |
+-----------+-------------+
3 rows in set (0.00 sec)

        查询的时候,这里的列,不能瞎写。select 指定的列,要么是带有聚合函数的列,要么就是group by 指定的列,不能指定一个非聚合非 group by 的列,否则无意义。举个例子:针对岗位查看员工姓名。查询结果如下:   这里的 name 列就是非聚合非 group by 的列。

select role, name from emp group by role;
+-----------+--------------+
| role      | name         |
+-----------+--------------+
| 学管师    | 刘玄德       |
| 老板      | 如来佛祖     |
| 讲师      | 孙悟空       |
+-----------+--------------+
3 rows in set (0.00 sec)

        还有更复杂的查询,如在分组的时候,可以指定条件筛选。这个时候就要搞清楚,筛选条件是在分组前,还是在分组后。

分组前筛选,使用where条件

例:求每个岗位的平均薪资,但是刨除 孙悟空 同学。

        这里的执行逻辑就是先将 孙悟空 同学除外,然后再进行分组,再求平均薪资。

select role, avg(salary) from emp where name != '孙悟空' group by role;
+-----------+-------------+
| role      | avg(salary) |
+-----------+-------------+
| 学管师    |   9500.0000 |
| 老板      | 110000.0000 |
| 讲师      |  11500.0000 |
+-----------+-------------+
3 rows in set (0.01 sec)

分组后筛选,使用having条件

例:求每个岗位的平均薪资,但是刨除 老板 这个岗位。

        这里的执行逻辑就是先分组,然后刨除 老板 这个岗位,再求平均薪资。

select role, avg(salary) from emp group by role having role != '老板';
+-----------+-------------+
| role      | avg(salary) |
+-----------+-------------+
| 学管师    |   9500.0000 |
| 讲师      |  11000.0000 |
+-----------+-------------+
2 rows in set (0.00 sec)

分组前后都筛选,同时使用where、having条件

例:先刨除 孙悟空 同学,然后求每个岗位的平均薪资,并且刨除 老板 这个岗位。

select role, avg(salary) from emp where name != '孙悟空' group by role having role != '老板';
+-----------+-------------+
| role      | avg(salary) |
+-----------+-------------+
| 学管师    |   9500.0000 |
| 讲师      |  11500.0000 |
+-----------+-------------+
2 rows in set (0.00 sec)

       联合查询 

        联合查询 又叫 多表查询。

        现有如下数据:    

select * from classes;
+----+-------------------------+-------------------------------------------------------------------+
| id | name                    | desc                                                              |
+----+-------------------------+-------------------------------------------------------------------+
|  1 | 计算机系2019级1班       | 学习了计算机原理、C和Java语言、数据结构和算法                     |
|  2 | 中文系2019级3班         | 学习了中国传统文学                                                |
|  3 | 自动化2019级5班         | 学习了机械自动化                                                  |
+----+-------------------------+-------------------------------------------------------------------+
3 rows in set (0.00 sec)





select * from course;
+----+--------------------+
| id | name               |
+----+--------------------+
|  1 | Java               |
|  2 | 中国传统文化       |
|  3 | 计算机原理         |
|  4 | 语文               |
|  5 | 高阶数学           |
|  6 | 英文               |
+----+--------------------+
6 rows in set (0.00 sec)








select * from student;
+----+-------+-----------------+------------------+------------+
| id | sn    | name            | qq_mail          | classes_id |
+----+-------+-----------------+------------------+------------+
|  1 | 09982 | 黑旋风李逵      | [email protected]  |          1 |
|  2 | 00835 | 菩提老祖        | NULL             |          1 |
|  3 | 00391 | 白素贞          | NULL             |          1 |
|  4 | 00031 | 许仙            | [email protected]    |          1 |
|  5 | 00054 | 不想毕业        | NULL             |          1 |
|  6 | 51234 | 好好说话        | [email protected]       |          2 |
|  7 | 83223 | tellme          | NULL             |          2 |
|  8 | 09527 | 老外学中文      | [email protected] |          2 |
+----+-------+-----------------+------------------+------------+
8 rows in set (0.00 sec)





select * from score;
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  70.5 |          1 |         1 |
|  98.5 |          1 |         3 |
|  33.0 |          1 |         5 |
|  98.0 |          1 |         6 |
|  60.0 |          2 |         1 |
|  59.5 |          2 |         5 |
|  33.0 |          3 |         1 |
|  68.0 |          3 |         3 |
|  99.0 |          3 |         5 |
|  67.0 |          4 |         1 |
|  23.0 |          4 |         3 |
|  56.0 |          4 |         5 |
|  72.0 |          4 |         6 |
|  81.0 |          5 |         1 |
|  37.0 |          5 |         5 |
|  56.0 |          6 |         2 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  80.0 |          7 |         2 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+
20 rows in set (0.00 sec)



       要进行联合查询,首先我们要先知道一个概念:笛卡尔积。 在SQL中呢,笛卡尔积是一种表与表之间的连接方式。两张表进行连接后,会对两张表中的每一行进行行组合。简单的说就是A表中的每一行都要与B表中的所有行进行一次组合。最后得到的组合表的行数是两张表的行之积,列数是两张表的列之和。这样呢就会导致很多的无效数据,所以我们需要对组合表进行一定的条件筛选。

例如:查询许仙同学的各科成绩
select * from student, score where student.id = score.student_id and student.name = '许仙';
+----+-------+--------+---------------+------------+-------+------------+-----------+
| id | sn    | name   | qq_mail       | classes_id | score | student_id | course_id |
+----+-------+--------+---------------+------------+-------+------------+-----------+
|  4 | 00031 | 许仙   | [email protected] |          1 |  67.0 |          4 |         1 |
|  4 | 00031 | 许仙   | [email protected] |          1 |  23.0 |          4 |         3 |
|  4 | 00031 | 许仙   | [email protected] |          1 |  56.0 |          4 |         5 |
|  4 | 00031 | 许仙   | [email protected] |          1 |  72.0 |          4 |         6 |
+----+-------+--------+---------------+------------+-------+------------+-----------+
4 rows in set (0.01 sec)



//这里再显示一下各科的名称
select * from student, course, score where student.id = score.student_id and score.course_id = course.id and student.name = '许仙';
+----+-------+--------+---------------+------------+----+-----------------+-------+------------+-----------+
| id | sn    | name   | qq_mail       | classes_id | id | name            | score | student_id | course_id |
+----+-------+--------+---------------+------------+----+-----------------+-------+------------+-----------+
|  4 | 00031 | 许仙   | [email protected] |          1 |  1 | Java            |  67.0 |          4 |         1 |
|  4 | 00031 | 许仙   | [email protected] |          1 |  3 | 计算机原理       |  23.0 |          4 |         3 |
|  4 | 00031 | 许仙   | [email protected] |          1 |  5 | 高阶数学         |  56.0 |          4 |         5 |
|  4 | 00031 | 许仙   | [email protected] |          1 |  6 | 英文             |  72.0 |          4 |         6 |
+----+-------+--------+---------------+------------+----+-----------------+-------+------------+-----------+
4 rows in set (0.00 sec)



//然后再去除其他无关信息
select student.name, score.score, course.name from student, course, score where student.id = score.student_id and score.course_id = course.id and student.name = '许仙';
+--------+-------+-----------------+
| name   | score | name            |
+--------+-------+-----------------+
| 许仙   |  67.0 | Java            |
| 许仙   |  23.0 | 计算机原理      |
| 许仙   |  56.0 | 高阶数学        |
| 许仙   |  72.0 | 英文            |
+--------+-------+-----------------+
4 rows in set (0.00 sec)

mysql>

多表查询一般实现步骤:

1,分析清楚需求中,涉及到的信息都在那些表里;

2,针对这多个表进行笛卡尔积;

3,筛选出其中的有效数据;(演示代码中用学生id和课程id作为关联条件)

4,结合需求中的条件,进一步加强条件;

5,针对列进行精简。

在上述例子中,还有另一查询方式:通过 join on 来进行查询。这种查询方式与前一种查询方式有些不同:首先在表明之间不再用逗号隔开了,而是用 join 来隔开;然后,查询条件用 on 来代替 where。 这两种查询方式在效果上是相同的。


//与另一种查询方式相比,就是做了个替换。
select student.name, score.score, course.name from student join course join score where student.id = score.student_id and score.course_id = course.id and student.name = '许仙';
+--------+-------+-----------------+
| name   | score | name            |
+--------+-------+-----------------+
| 许仙   |  67.0 | Java            |
| 许仙   |  23.0 | 计算机原理      |
| 许仙   |  56.0 | 高阶数学        |
| 许仙   |  72.0 | 英文            |
+--------+-------+-----------------+
4 rows in set (0.00 sec)
例:查询所有同学的总成绩,以及同学的个人信息。
select * from student, score where student.id = score.student_id;
+----+-------+-----------------+-----------------+------------+-------+------------+-----------+
| id | sn    | name            | qq_mail         | classes_id | score | student_id | course_id |
+----+-------+-----------------+-----------------+------------+-------+------------+-----------+
|  1 | 09982 | 黑旋风李逵      | [email protected] |          1 |  70.5 |          1 |         1 |
|  1 | 09982 | 黑旋风李逵      | [email protected] |          1 |  98.5 |          1 |         3 |
|  1 | 09982 | 黑旋风李逵      | [email protected] |          1 |  33.0 |          1 |         5 |
|  1 | 09982 | 黑旋风李逵      | [email protected] |          1 |  98.0 |          1 |         6 |
|  2 | 00835 | 菩提老祖        | NULL            |          1 |  60.0 |          2 |         1 |
|  2 | 00835 | 菩提老祖        | NULL            |          1 |  59.5 |          2 |         5 |
|  3 | 00391 | 白素贞          | NULL            |          1 |  33.0 |          3 |         1 |
|  3 | 00391 | 白素贞          | NULL            |          1 |  68.0 |          3 |         3 |
|  3 | 00391 | 白素贞          | NULL            |          1 |  99.0 |          3 |         5 |
|  4 | 00031 | 许仙            | [email protected]   |          1 |  67.0 |          4 |         1 |
|  4 | 00031 | 许仙            | [email protected]   |          1 |  23.0 |          4 |         3 |
|  4 | 00031 | 许仙            | [email protected]   |          1 |  56.0 |          4 |         5 |
|  4 | 00031 | 许仙            | [email protected]   |          1 |  72.0 |          4 |         6 |
|  5 | 00054 | 不想毕业        | NULL            |          1 |  81.0 |          5 |         1 |
|  5 | 00054 | 不想毕业        | NULL            |          1 |  37.0 |          5 |         5 |
|  6 | 51234 | 好好说话        | [email protected]      |          2 |  56.0 |          6 |         2 |
|  6 | 51234 | 好好说话        | [email protected]      |          2 |  43.0 |          6 |         4 |
|  6 | 51234 | 好好说话        | [email protected]      |          2 |  79.0 |          6 |         6 |
|  7 | 83223 | tellme          | NULL            |          2 |  80.0 |          7 |         2 |
|  7 | 83223 | tellme          | NULL            |          2 |  92.0 |          7 |         6 |
+----+-------+-----------------+-----------------+------------+-------+------------+-----------+
20 rows in set (0.00 sec)


//此时如何对每个学生的成绩进行求和呢?

//我们考虑分组,通过分组来对每个同学的成绩进行求和。
select * from student, score where student.id = score.student_id group by student.id;
+----+-------+-----------------+-----------------+------------+-------+------------+-----------+
| id | sn    | name            | qq_mail         | classes_id | score | student_id | course_id |
+----+-------+-----------------+-----------------+------------+-------+------------+-----------+
|  1 | 09982 | 黑旋风李逵      | [email protected] |          1 |  70.5 |          1 |         1 |
|  2 | 00835 | 菩提老祖        | NULL            |          1 |  60.0 |          2 |         1 |
|  3 | 00391 | 白素贞          | NULL            |          1 |  33.0 |          3 |         1 |
|  4 | 00031 | 许仙            | [email protected]   |          1 |  67.0 |          4 |         1 |
|  5 | 00054 | 不想毕业        | NULL            |          1 |  81.0 |          5 |         1 |
|  6 | 51234 | 好好说话        | [email protected]      |          2 |  56.0 |          6 |         2 |
|  7 | 83223 | tellme          | NULL            |          2 |  80.0 |          7 |         2 |
+----+-------+-----------------+-----------------+------------+-------+------------+-----------+
7 rows in set (0.01 sec)

//分组后, 每个同学一条记录,但是呢,成绩并不是总分。

//要计算总分,要通过行之间的运算,这样就要用到聚合函数了
select student.name, sum(score.score) from student, score where student.id = score.student_id group by student.id;
+-----------------+------------------+
| name            | sum(score.score) |
+-----------------+------------------+
| 黑旋风李逵      |            300.0 |
| 菩提老祖        |            119.5 |
| 白素贞          |            200.0 |
| 许仙            |            218.0 |
| 不想毕业        |            118.0 |
| 好好说话        |            178.0 |
| tellme          |            172.0 |
+-----------------+------------------+
7 rows in set (0.01 sec)



       联合查询---内连接与外连接

        现有如下数据:

select * from student;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 张三   |
|    2 | 李四   |
|    3 | 王五   |
+------+--------+
3 rows in set (0.00 sec)




select * from score;
+------------+-------+
| student_id | score |
+------------+-------+
|          1 |    80 |
|          2 |    75 |
|          4 |    89 |
+------------+-------+
3 rows in set (0.00 sec)
内连接:在内连接中,只有当两个表中都存在与连接标准相匹配的数据时,才会保留这些数据。包括重复数据。
select * from student join score on student.id = score.student_id;
+------+--------+------------+-------+
| id   | name   | student_id | score |
+------+--------+------------+-------+
|    1 | 张三   |          1 |    80 |
|    2 | 李四   |          2 |    75 |
+------+--------+------------+-------+
2 rows in set (0.00 sec)

//这里再演示一下 内连接保留重复数据

//先在 student 表中插入一条相同的数据
insert into student values (2, '李四');
Query OK, 1 row affected (0.01 sec)



//查看此时的 student 表
select * from student;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 张三   |
|    2 | 李四   |
|    3 | 王五   |
|    2 | 李四   |
+------+--------+
4 rows in set (0.00 sec)


//进行内连接查询

select * from student join score on student.id = score.student_id;
+------+--------+------------+-------+
| id   | name   | student_id | score |
+------+--------+------------+-------+
|    1 | 张三   |          1 |    80 |
|    2 | 李四   |          2 |    75 |
|    2 | 李四   |          2 |    75 |
+------+--------+------------+-------+
3 rows in set (0.00 sec)

多表内连接:语法:select * from 表1 join 表2 on 条件1 join 表3 on 条件2 ;
select * from student join score on student.id = score.student_id join course on student.id = course.student_id;
+------+--------+------------+-------+------------+--------+
| id   | name   | student_id | score | student_id | name   |
+------+--------+------------+-------+------------+--------+
|    1 | 张三   |          1 |    80 |          1 | 语文   |
+------+--------+------------+-------+------------+--------+
1 row in set (0.00 sec)

 

外连接:包括左外连接,右外连接。
左外连接:在 join 前加 left ,保留左表的全部数据;
select * from student left join score on student.id = score.student_id;
+------+--------+------------+-------+
| id   | name   | student_id | score |
+------+--------+------------+-------+
|    1 | 张三   |          1 |    80 |
|    2 | 李四   |          2 |    75 |
|    2 | 李四   |          2 |    75 |
|    3 | 王五   |       NULL |  NULL |
+------+--------+------------+-------+
4 rows in set (0.00 sec)
右外连接:在 join 前加 right ,保留右表的全部数据;
select * from student right join score on student.id = score.student_id;
+------+--------+------------+-------+
| id   | name   | student_id | score |
+------+--------+------------+-------+
|    1 | 张三   |          1 |    80 |
|    2 | 李四   |          2 |    75 |
|    2 | 李四   |          2 |    75 |
| NULL | NULL   |          4 |    89 |
+------+--------+------------+-------+
4 rows in set (0.00 sec)

       补充

自连接:  将行转成列   当需要比较行之间的关系时,可以考虑自连接,但是代价是相当的大,产生的数据中,绝大多数是无效数据

自连接语法: select * from 表1 as 别名1 join 表1 as 别名2 on 条件;

子查询:  将多个联合查询合并成一个查询,将查询中的一个值用另外一个查询语句来代替。(查询代价也是很大,基本不用)

        


       联合查询用到的代码
create table classes(id int primary key auto_increment, name varchar(20), `desc` varchar(100));


create table student (id int primary key auto_increment, sn varchar(20), name varchar(20),qq_mail varchar(20),classes_id int);


create table course(id int primary key auto_increment, name varchar(20));


create table score(score decimal(3,1), student_id int, course_id int);


mysql> insert into classes(name, `desc`) values
    -> ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
    -> ('中文系2019级3班','学习了中国传统文学'),
    -> ('自动化2019级5班','学习了机械自动化');


mysql> insert into student(sn, name, qq_mail, classes_id) values
    -> ('09982','黑旋风李逵','[email protected]',1),
    -> ('00835','菩提老祖',null,1),
    -> ('00391','白素贞',null,1),
    -> ('00031','许仙','[email protected]',1),
    -> ('00054','不想毕业',null,1),
    -> ('51234','好好说话','[email protected]',2),
    -> ('83223','tellme',null,2),
    -> ('09527','老外学中文','[email protected]',2);


mysql> insert into course(name) values
    -> ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');


mysql> insert into score(score, student_id, course_id) values
    -> -- 黑旋风李逵
    -> (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
    -> -- 菩提老祖
    -> (60, 2, 1),(59.5, 2, 5),
    -> -- 白素贞
    -> (33, 3, 1),(68, 3, 3),(99, 3, 5),
    -> -- 许仙
    -> (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
    -> -- 不想毕业
    -> (81, 5, 1),(37, 5, 5),
    -> -- 好好说话
    -> (56, 6, 2),(43, 6, 4),(79, 6, 6),
    -> -- tellme
    -> (80, 7, 2),(92, 7, 6);


        我是专注学习的章鱼哥~

你可能感兴趣的:(数据库,数据库)