14-mysql多表查询

1、多表连接介绍

1)什么是多表连接?

查询的内容来自多张表。

2)为什么要多表连接?

记录信息是在多张表中记录的,但是我们取的信息,可能就要从多张表取出。

3)数据为什么要放在多张表里?

规范\效率

4)MySQL join多表连接知识笔记

https://www.cnblogs.com/oldboy666/p/15640387.html

2、MySQL join多表连接知识深入浅出介绍及实践

1. SQL join多表连接介绍(老男孩DBA课程内容)

SQL Join子句,主要用在select语句中,把两个或多个表的行结合起来,基于这些表之间的共同字段(往往是id字段)来查询,从多个表中返回满足条件的所有行。

2.常见join子句类型

常见join子句类型有INNER JOIN(同JOIN)、LEFT JOIN、RIGHT JOIN、FULL JOIN,其中第一种为内连接,后三种为外连接。

3、不同的join子句类型区别如下图所示:

4、实践数据准备

# 数据准备
# 创建一个表a,id字段是整数类型,值不允许为空,主键,自动增长主键。name字段是字符类型,非空。age字段 小整数类型。
create table a(id int not null primary key auto_increment,name varchar(20) not null,age tinyint);
# 创建一个表b,aid字段是整数类型,非空。city字段字符类型,非空,telnum字段,字符类型。
create table b(aid int not null,city varchar(20) not null,telnum int;
# 往a表中插入数据,
insert into a values(1,'oldboy',35),(2,'oldgirl',28),(3,'inca',22),(5,'zs',23);
insert into b values(1,'bj',135),(2,'sz',189),(3,'sh',166),(4,'hz',187);

#1.建表语句和内容插入。a是左边的表,b是右边的表#2.最终数据结果。
mysql> select * from a;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | oldboy  |   35 |
|  2 | oldgirl |   28 |
|  3 | inca    |   22 |
|  5 | zs      |   23 |
+----+---------+------+
4 rows in set (0.00 sec)
 
mysql> select * from b;
+-----+------+--------+
| aid | city | telnum |
+-----+------+--------+
|   1 | bj   | 135    |
|   2 | sz   | 189    |
|   3 | sh   | 166    |
|   4 | hz   | 187    |
+-----+------+--------+
4 rows in set (0.00 sec)
#提示:注意两个表的ID列有相同的id,也有不同的ID

5、常用连接方式实践

(1)笛卡尔乘积

笛卡尔乘积的作用是以每一张表的每一行和另一张表做关联,逐行对比。
执行select * from a,b;演示笛卡尔乘积结果,其中的行id和aid相等的列合并才是有意义的,其它比对行都是无意义的。

mysql> select * from a,b;
+----+---------+------+-----+------+--------+
| id | name    | age  | aid | city | telnum |
+----+---------+------+-----+------+--------+
|  5 | zs      |   23 |   1 | bj   | 135    |
|  3 | inca    |   22 |   1 | bj   | 135    |
|  2 | oldgirl |   28 |   1 | bj   | 135    |
|  1 | oldboy  |   35 |   1 | bj   | 135    |
|  5 | zs      |   23 |   2 | sz   | 189    |
|  3 | inca    |   22 |   2 | sz   | 189    |
|  2 | oldgirl |   28 |   2 | sz   | 189    |
|  1 | oldboy  |   35 |   2 | sz   | 189    |
|  5 | zs      |   23 |   3 | sh   | 166    |
|  3 | inca    |   22 |   3 | sh   | 166    |
|  2 | oldgirl |   28 |   3 | sh   | 166    |
|  1 | oldboy  |   35 |   3 | sh   | 166    |
|  5 | zs      |   23 |   4 | hz   | 187    |
|  3 | inca    |   22 |   4 | hz   | 187    |
|  2 | oldgirl |   28 |   4 | hz   | 187    |
|  1 | oldboy  |   35 |   4 | hz   | 187    |
+----+---------+------+-----+------+--------+
16 rows in set (0.00 sec)

(2)内连接(inner join)实践

内连接是生产最常见的连接,只输出关联ID匹配的行。内连接有三种语句,都是等同的。

# a表连接b表 a的id等于b的aid
mysql> select * from a join b on a.id=b.aid;         #<==省略了inner关键词。
mysql> select * from a inner join b on a.id=b.aid;   #<==带inner关键词。
mysql> select * from a,b where a.id=b.aid;

以上3个语句输出的信息相同,即为两个表中id相同的行信息。

+----+---------+------+-----+------+--------+
| id | name    | age  | aid | city | telnum |
+----+---------+------+-----+------+--------+
|  1 | oldboy  |   35 |   1 | bj   | 135    |
|  2 | oldgirl |   28 |   2 | sz   | 189    |
|  3 | inca    |   22 |   3 | sh   | 166    |

(3)左外连接(left join)实践

LEFT JOIN子句会返回左表全部行和右表满足ON关联条件行,如果左表行在右表中没有匹配,那么这一行右表中对应数据用NULL代替。

mysql> select * from a left join b on a.id=b.aid; #执行SQL输出结果如下。
+----+---------+------+------+------+--------+
| id | name    | age  | aid  | city | telnum |
+----+---------+------+------+------+--------+
|  1 | oldboy  |   35 |    1 | bj   | 135    |
|  2 | oldgirl |   28 |    2 | sz   | 189    |
|  3 | inca    |   22 |    3 | sh   | 166    |
|  5 | zs      |   23 | NULL | NULL | NULL   |
+----+---------+------+------+------+--------+

(4)右外连接(right join)实践

RIGHT JOIN子句会右表全部行和左表满足ON关联条件行,如果右表行在左表中没有匹配,那么这一行左表中对应数据用NULL代替。

mysql> select * from a right outer join b on a.id=b.aid;  #<==outer可省略。
+------+---------+------+-----+------+--------+
| id   | name    | age  | aid | city | telnum |
+------+---------+------+-----+------+--------+
|    1 | oldboy  |   35 |   1 | bj   | 135    |
|    2 | oldgirl |   28 |   2 | sz   | 189    |
|    3 | inca    |   22 |   3 | sh   | 166    |
| NULL | NULL    | NULL |   4 | hz   | 187    |
+------+---------+------+-----+------+--------+
mysql> select * from a right join b on a.id=b.aid;
+------+---------+------+-----+------+--------+
| id   | name    | age  | aid | city | telnum |
+------+---------+------+-----+------+--------+
|    1 | oldboy  |   35 |   1 | bj   | 135    |
|    2 | oldgirl |   28 |   2 | sz   | 189    |
|    3 | inca    |   22 |   3 | sh   | 166    |
| NULL | NULL    | NULL |   4 | hz   | 187    |
+------+---------+------+-----+------+--------+

(5)外连接(outer join)实践

outer join有的库叫做FULL JOIN会返回左表和右表所有的行。如果其中一个表的数据行在另一个表中没有匹配的行,那么对面的数据用NULL代替,不过mysql暂不支持这种连接,但可以用union all连接左连接和右连接来实现。

mysql> (select * from a left join b on a.id=b.aid)
    -> union
    -> (select * from a right join b on a.id=b.aid);
+------+---------+------+------+------+--------+
| id   | name    | age  | aid  | city | telnum |
+------+---------+------+------+------+--------+
|    1 | oldboy  |   35 |    1 | bj   | 135    |
|    2 | oldgirl |   28 |    2 | sz   | 189    |
|    3 | inca    |   22 |    3 | sh   | 166    |
|    5 | zs      |   23 | NULL | NULL | NULL   |
| NULL | NULL    | NULL |    4 | hz   | 187    |
+------+---------+------+------+------+--------+

5.老男孩后记:

有关mysql的join,其实可以简单得执行? join,查看MySQL支持的连接类型及例子,一般人我都不告诉他。

joined_table: {
    table_reference {[INNER | CROSS] JOIN | STRAIGHT_JOIN} table_factor [join_specification]
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_specification
  | table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor
}
join_specification: {
    ON search_condition
  | USING (join_column_list)
}

3、MySQL多表连接实践

笔记移步链接:

https://www.cnblogs.com/oldboy666/p/15637461.html

(1)准备工作(表名和表结构)

use school
student :学生表
sno:  学号
sname:学生姓名
sage: 学生年龄
ssex: 学生性别
 
teacher :教师表
tno:     教师编号
tname:   教师名字
 
course :课程表
cno:  课程编号
cname:课程名字
tno:  教师编号
 
sc  :成绩表
sno:  学号
cno:  课程编号
score:成绩

(2)各个表关联关系

(3)生成表格及插入数据

/* oldboyedu.com by oldboy
Date: 05/12/2021 10:32:02 */

# 设置MySQL客户端字符集的语句
SET NAMES utf8mb4;
# 这是一个用于设置MySQL外键检查的语句
SET FOREIGN_KEY_CHECKS = 0;
# 创建一个school数据库,指定数据库的字符集为utf8mb4
create database school CHARSET=utf8mb4;
# 进入到school数据库
use school;
-- ----------------------------
-- Table structure for course
-- ----------------------------
# 删除cource表,只有在表格存在的情况下才执行删除操作。
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `cno` int(11) NOT NULL COMMENT '课程编号',
  `cname` varchar(20) NOT NULL COMMENT '课程名字',
  `tno` int(11) NOT NULL COMMENT '教师编号',
  PRIMARY KEY (`cno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of course
-- ----------------------------
BEGIN;
INSERT INTO `course` VALUES (1001, 'linux', 101);
INSERT INTO `course` VALUES (1002, 'python', 102);
INSERT INTO `course` VALUES (1003, 'mysql', 103);
INSERT INTO `course` VALUES (1004, 'k8s', 108);
COMMIT;
-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc` (
  `sno` int(11) NOT NULL COMMENT '学号',
  `cno` int(11) NOT NULL COMMENT '课程编号',
  `score` int(11) NOT NULL DEFAULT '0' COMMENT '成绩'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of sc
-- ----------------------------
BEGIN;
INSERT INTO `sc` VALUES (1, 1001, 80);
INSERT INTO `sc` VALUES (1, 1002, 59);
INSERT INTO `sc` VALUES (2, 1002, 90);
INSERT INTO `sc` VALUES (2, 1003, 100);
INSERT INTO `sc` VALUES (3, 1001, 99);
INSERT INTO `sc` VALUES (3, 1003, 40);
INSERT INTO `sc` VALUES (4, 1001, 79);
INSERT INTO `sc` VALUES (4, 1002, 61);
INSERT INTO `sc` VALUES (4, 1003, 99);
INSERT INTO `sc` VALUES (5, 1003, 40);
INSERT INTO `sc` VALUES (6, 1001, 89);
INSERT INTO `sc` VALUES (6, 1003, 77);
INSERT INTO `sc` VALUES (7, 1001, 67);
INSERT INTO `sc` VALUES (7, 1003, 82);
INSERT INTO `sc` VALUES (8, 1001, 70);
INSERT INTO `sc` VALUES (9, 1003, 80);
INSERT INTO `sc` VALUES (10, 1003, 96);
COMMIT;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `sno` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
  `sname` varchar(20) NOT NULL COMMENT '姓名',
  `sage` tinyint(3) unsigned NOT NULL COMMENT '年龄',
  `ssex` enum('f','m') NOT NULL DEFAULT 'm' COMMENT '性别',
  PRIMARY KEY (`sno`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of student
-- ----------------------------
BEGIN;
INSERT INTO `student` VALUES (1, 'zhangs', 18, 'm');
INSERT INTO `student` VALUES (2, 'lisi88', 18, 'm');
INSERT INTO `student` VALUES (3, 'wangwu', 22, 'm');
INSERT INTO `student` VALUES (4, 'laoliu', 19, 'f');
INSERT INTO `student` VALUES (5, 'zhao4m', 18, 'm');
INSERT INTO `student` VALUES (6, 'liuxia', 18, 'm');
INSERT INTO `student` VALUES (7, 'matian', 19, 'f');
INSERT INTO `student` VALUES (8, 'oldboy', 20, 'm');
INSERT INTO `student` VALUES (9, 'oldgirl', 20, 'f');
INSERT INTO `student` VALUES (10, 'oldpod', 25, 'm');
COMMIT;
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `tno` int(11) NOT NULL COMMENT '教师编号',
  `tname` varchar(20) NOT NULL COMMENT '教师名字',
  PRIMARY KEY (`tno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of teacher
-- ----------------------------
# 这是一个用于启动事务的语句。在一个事务中,可以包含多条SQL语句,要么全部执行成功,要么全部失败回滚。事务可以保证一组相关操作的一致性和完整性。
BEGIN;
INSERT INTO `teacher` VALUES (101, 'oldboy');
INSERT INTO `teacher` VALUES (102, 'ran');
INSERT INTO `teacher` VALUES (103, 'lisir');
INSERT INTO `teacher` VALUES (104, 'Tim');
INSERT INTO `teacher` VALUES (105, 'Jack');
# 这是一个用于提交事务的语句。在执行了一组SQL语句后,如果没有出现错误,通过COMMIT;语句将事务提交,使所有的插入操作生效。
COMMIT;
# 这是一个用于设置MySQL外键检查的语句,上面给关了,插入完成之后咱们再给开启。
SET FOREIGN_KEY_CHECKS = 1;
 
项目构建:
source /root/school.sql

查看插入的数据

mysql> select * from course;
+------+--------+-----+
| cno  | cname  | tno |
+------+--------+-----+
| 1001 | linux  | 101 |
| 1002 | python | 102 |
| 1003 | mysql  | 103 |
| 1004 | k8s    | 108 |
+------+--------+-----+
4 rows in set (0.00 sec)

mysql> select * from sc;
+-----+------+-------+
| sno | cno  | score |
+-----+------+-------+
|   1 | 1001 |    80 |
|   1 | 1002 |    59 |
|   2 | 1002 |    90 |
|   2 | 1003 |   100 |
|   3 | 1001 |    99 |
|   3 | 1003 |    40 |
|   4 | 1001 |    79 |
|   4 | 1002 |    61 |
|   4 | 1003 |    99 |
|   5 | 1003 |    40 |
|   6 | 1001 |    89 |
|   6 | 1003 |    77 |
|   7 | 1001 |    67 |
|   7 | 1003 |    82 |
|   8 | 1001 |    70 |
|   9 | 1003 |    80 |
|  10 | 1003 |    96 |
+-----+------+-------+
17 rows in set (0.00 sec)
mysql> select * from student;
+-----+---------+------+------+
| sno | sname   | sage | ssex |
+-----+---------+------+------+
|   1 | zhangs  |   18 | m    |
|   2 | lisi88  |   18 | m    |
|   3 | wangwu  |   22 | m    |
|   4 | laoliu  |   19 | f    |
|   5 | zhao4m  |   18 | m    |
|   6 | liuxia  |   18 | m    |
|   7 | matian  |   19 | f    |
|   8 | oldboy  |   20 | m    |
|   9 | oldgirl |   20 | f    |
|  10 | oldpod  |   25 | m    |
+-----+---------+------+------+
10 rows in set (0.00 sec)

mysql> select * from teacher;
+-----+--------+
| tno | tname  |
+-----+--------+
| 101 | oldboy |
| 102 | ran    |
| 103 | lisir  |
| 104 | Tim    |
| 105 | Jack   |
+-----+--------+
5 rows in set (0.00 sec)

(4)多表连接查询数据实践

1.统计下每个学生的[平均]成绩

解答:
#a.找出所有相关表student、sc
#b.列举要查询的列,student.sname,sc.score
#c.找到以上表的直接或间接关联条件,student.sno,sc.sno
# 多表查询,从student表和sc表中查询学生的姓名和平均成绩然后根据sno学号进行去重整合起来
mysql> SELECT student.sname,AVG(sc.score) 
       FROM student JOIN sc ON student.sno=sc.sno 
       GROUP BY student.sno; ###用学号代替sname,防止重名
+---------+---------------+
| sname   | AVG(sc.score) |
+---------+---------------+
| zhangs  |       69.5000 |
| lisi88  |       95.0000 |
...省略若干行...
| oldgirl |       80.0000 |
| oldpod  |       96.0000 |
+---------+---------------+

2.统计每位学生学习的课程门数

解答:
#a.找出所有相关表student、sc
#b.涉及的列student.sname,sc.score(学生有几门成绩,就选择了几门课)
#c.选择的列student.sname count(sc.score)
# 多表查询,从student表和sc表中查询学生的名字和有几门成绩进行判断学生学习的课程门数、COUNT返回指定组中数据的数量。
mysql> SELECT student.sname,COUNT(sc.score) 
       FROM student JOIN sc  ON student.sno=sc.sno 
       GROUP BY student.sno;
+---------+-----------------+
| sname   | COUNT(sc.score) |
+---------+-----------------+
| zhangs  |               2 |
| lisi88  |               2 |
...省略若干行...
| oldgirl |               1 |
| oldpod  |               1 |
+---------+-----------------+

3.统计每位老师所教的课程门数

# 多表查tearcher表的老师名称和couse表的课程数量
分析题意:
#a.找出相关表teacher、course
#b.涉及的列teacher.tname  course.cname
#c.select选择的列teacher.tno=course.tno
#d.分组条件:GROUP BY teacher.tno
mysql> SELECT teacher.tname,COUNT(course.cname) 
       FROM teacher JOIN course ON teacher.tno=course.tno 
       GROUP BY teacher.tno;
+--------+---------------------+
| tname  | COUNT(course.cname) |
+--------+---------------------+
| oldboy |                   1 |
| ran    |                   1 |
| lisir  |                   1 |
+--------+---------------------+


# 增加oldboy老师教的课程门数
mysql> insert into course values(1005,'mysql',101);
mysql> SELECT teacher.tname,COUNT(course.cname)  
       FROM teacher JOIN course  
       ON teacher.tno=course.tno  
       GROUP BY teacher.tno;
+--------+---------------------+
| tname  | COUNT(course.cname) |
+--------+---------------------+
| oldboy |                   2 |
| ran    |                   1 |
| lisir  |                   1 |
+--------+---------------------+

4.每位老师所教的课程门数和名称

# 查询teacher表的老师名称和course表的课程名称进行统计数量还有把课程名称进行展示出来
mysql> SELECT teacher.tname,COUNT(course.cname),GROUP_CONCAT(course.cname)
    -> FROM teacher JOIN course ON teacher.tno=course.tno
    -> GROUP BY teacher.tno;
+--------+---------------------+----------------------------+
| tname  | COUNT(course.cname) | GROUP_CONCAT(course.cname) |
+--------+---------------------+----------------------------+
| oldboy |                   1 | linux                      |
| ran    |                   1 | python                     |
| lisir  |                   1 | mysql                      |
+--------+---------------------+----------------------------+

5.每位学生学习的课程门数和名称

#5.每位学生学习的课程门数和名称
# 查询student表的学生名称和sc表的成绩数量还有course表的课程名称
mysql> SELECT student.sname,COUNT(sc.score),GROUP_CONCAT(course.cname)
    -> FROM student
    -> JOIN sc
    -> ON student.sno=sc.sno
    -> JOIN course
    -> ON sc.cno=course.cno
    -> GROUP BY student.sno;
+---------+-----------------+----------------------------+
| sname   | COUNT(sc.score) | GROUP_CONCAT(course.cname) |
+---------+-----------------+----------------------------+
| zhangs  |               2 | python,linux               |
...省略若干行...
| oldboy  |               1 | linux                      |
| oldgirl |               1 | mysql                      |
| oldpod  |               1 | mysql                      |
+---------+-----------------+----------------------------+

(5)多表SQL考试题

1. 统计zhangs,学习了几门课

误区:几门课,不是去课程表查,而是成绩表查。因为学生表和成绩表是关联的拥有学生学号的同一字段sno。
   选择列:student.sname,count(sc.cno)
   涉及表:student,sc
   关联条件:student.sno,sc.sno
   查询条件:where student.sname='zhangs';
   分组条件:group by student.sno;
   ======================================
   
mysql> select student.sname,count(sc.cno)          #查询学生表的学生名称和统计成绩表的课程编号
    -> from student join sc on student.sno=sc.sno  # 从学生表和成绩表进行表关联,以学号的方式进行关联
    -> where student.sname='zhangs'  			   # 筛选学生名称为zhangs的
    ->  group by student.sno;   				   # 根据学号进行分组去重
+--------+---------------+
| sname  | count(sc.cno) |
+--------+---------------+
| zhangs |             2 |
+--------+---------------+
1 row in set (0.01 sec)

2. 查询zhangs,学习的课程名称有哪些?

   分析:
   选择列:student.sname,group_concat(course.cname)
   涉及表:student,course,sc
   关联条件:student.sno=sc.sno,sc.cno=course.cno
   查询条件:where student.sname='zhangs'
   分组条件:group by student.sno;
   ======================================

mysql> select student.sname,group_concat(course.cname) # 查询学生表的学生名称和课程表的课程名称
    -> from  student join sc on student.sno=sc.sno     # 从学生表和成绩表以学号的方式进行关联
    -> join course on sc.cno=course.cno                # 课程表关联成绩表以课程编号进行关联
    ->  where student.sname='zhangs'                   # 筛选学生名字为zhangs的
    ->  group by student.sno;                          # 根据学号进行分组去重
+--------+----------------------------+
| sname  | group_concat(course.cname) |
+--------+----------------------------+
| zhangs | linux,python               |
+--------+----------------------------+
1 row in set (0.01 sec)

3. 查询oldboy老师教的学生名.

   分析:
   选择列:teacher.tname,group_concat(student.sname)
   涉及表:teacher,course,sc,student
   关联条件:teacher.tno=course.tno,course.cno=sc.cno,sc.sno=student.sno
   查询条件:where teacher.tname='oldboy'
   分组条件:group by teacher.tno;
    ======================================
mysql> SELECT teacher.tname,GROUP_CONCAT(student.sname) # 查询教师表的教师名称和学生表的学生名称
    -> FROM teacher JOIN course ON teacher.tno=course.tno #教师表的教师编号和课程表的教师编号进行关联
    -> JOIN sc ON course.cno=sc.cno  # 课程表的课程编号和成绩表的课程编号进行关联
    -> JOIN student ON sc.sno=student.sno  # 成绩表的学号和学生表的学号进行关联
    -> WHERE teacher.tname='oldboy'        # 筛选老师的名称叫oldboy
    -> GROUP BY teacher.tno;               # 根据老师的编号进行去重
+--------+-------------------------------------------+
| tname  | GROUP_CONCAT(student.sname)               |
+--------+-------------------------------------------+
| oldboy | zhangs,wangwu,laoliu,liuxia,matian,oldboy |
+--------+-------------------------------------------+
1 row in set (0.01 sec)

4. 查询oldboy所教课程的平均分数

   分析:
   选择列:teacher.tname,AVG(sc.score) 
   涉及表:teacher,course,sc 
   关联条件:teacher.tno=course.tno,course.cno=sc.cno
   查询条件:where teacher.tname='oldboy'
   分组条件:group by teacher.tno;
    ======================================
    
mysql> select teacher.tname,avg(sc.score)  # 查询教师表的教师名称和成绩表的平均成绩
    -> from teacher join course on teacher.tno=course.tno #根据教师表的教师编号和课程表的教师编号进行关联
    -> join sc on course.cno=sc.cno        # 根据课程表的课程编号和成绩表的课程编号进行关联
    -> where teacher.tname='oldboy'        # 筛选老师的名称为oldboy
    -> group by teacher.tno;               # 根据老师的编号进行去重
+--------+---------------+
| tname  | avg(sc.score) |
+--------+---------------+
| oldboy |       80.6667 |
+--------+---------------+
1 row in set (0.00 sec)

5.查询教师表的教师名称和学生表的学生名称

mysql> SELECT sname AS student_names, teacher_names  
    -> FROM (                                        
    ->   SELECT GROUP_CONCAT(sname) AS sname  
    ->   FROM student                        
    -> ) AS students    
    -> LEFT JOIN (     
    ->   SELECT GROUP_CONCAT(tname) AS teacher_names 
    ->   FROM teacher
    -> ) AS teachers ON 1=1;
+------------------------------------------------------------------------+---------------------------+
| student_names                                                          | teacher_names             |
+------------------------------------------------------------------------+---------------------------+
| zhangs,lisi88,wangwu,laoliu,zhao4m,liuxia,matian,oldboy,oldgirl,oldpod | oldboy,ran,lisir,Tim,Jack |
+------------------------------------------------------------------------+---------------------------+
1 row in set (0.00 sec)
6. 查询ran所教的不及格的学生姓名

7. 查询所有老师所教学生不及格的信息

8. 查询平均成绩大于60分的同学的学号和平均成绩;

9. 查询所有同学的学号、姓名、选课数、总成绩;

10.查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分

11.查询每门课程被选修的学生数

12.查询出只选修了一门课程的全部学生的学号和姓名

13.查询选修课程门数超过1门的学生信息

14.查询平均成绩大于85的所有学生的学号、姓名和平均成绩

15.统计各位老师,所教课程的及格率

16.统计每门课程:优秀(85分以上),良好(70-85),一般(60-70),不及格(小于60)的学生列表

补充:别名应用 as

a. 列别名 b. 表别名
SELECT student.sno as '学号',student.sname as '姓名',AVG(sc.score) as '平均分'
FROM student
JOIN sc ON student.sno=sc.sno
GROUP BY student.sno
HAVING AVG(sc.score)>85

+--------+--------+-----------+
| 学号   | 姓名   | 平均分    |
+--------+--------+-----------+
|      2 | lisi88 |   95.0000 |
|     10 | oldpod |   96.0000 |
+--------+--------+-----------+

其他:

1)专业DBA方向扩展作业.
    1.子查询 2.内置函数 3.存储过程,函数,触发器,事件,视图。
    2.整理以上名词及简单使用:
	1)是什么?2)作用?3)简单使用。
	
2)推荐使用sqlyog客户端学习本章内容,方便换行。

3)SQL语句复杂程度及互联网和传统企业区别。

4)预习:MySQL SQL语句执行过程详解
https://www.jianshu.com/p/0c744fbb60e0
https://www.cnblogs.com/dh17/articles/15312393.html
https://blog.csdn.net/a745233700/article/details/113927318

SQL企业面试题:

1.2 SQL篇
1.2.1 请简述select语句的各个子句的执行顺序?
1.2.2 请列举SQL语句的种类和代表命令?
1.2.3 请简述SQL_MODE的作用?ONLY_FULL_GROUP_BY是干什么用的?
1.2.4 请简述MySQL utf8和utf8mb4区别?
1.2.5 请简述tinyint\int\bigint 如何计算的存储位数?
1.2.6 请简述char(10)和varchar(10)的区别,生产如何选择?并阐述为什么?
1.2.7 请简述datetime和timestamp区别?
1.2.8 请简述你们数据库开发过程,选择数据类型的规范是什么?

最长SQL
https://blog.csdn.net/jaketseng/article/details/2206896
posted @ 2023-07-27 17:34  猛踢瘸子nei条好腿  阅读(32)  评论(0)    收藏  举报