一、MySQL多表查询和子查询

1、联结查询

联结查询:事先将两张或多张表join,根据join的结果进行查询

  • 交叉联结:效率很低

  • 自然联结:也叫等值联结

  • 外联结:常用的

   左外联结:只保留出现在左外连接运算之前(左边)的关系中的元组;

    left_tb LEFT JOIN right_tb ON 连接条件

   右外联结:只保留出现在右外连接运算之后(右边)的关系中的元组;

    left_tb RIGHT JOIN right_tb ON 连接条件

   全外联结:mysql不支持此联结

  • 自联结

说明:在查询中还可以使用别名的方法来缩减代码,而别名可分为:表别名和字段别名,两者的应用等大大减少代码量。

2、子查询

子查询:在查询中嵌套的查询。

用于WHERE中的子查询:

  • 用于比较表达式中的子查询,子查询的返回值只能有一个;

  • 用于EXISTS中的子查询,判断存在与否;

  • 用于IN中的子查询,判断存在于指定列表中;

用于FROM中子查询:

   SELECT alias.col,... FROM (SELECT clause) AS alias WHERE condition

 注意:MySQL不擅长于子查询:应该避免使用子查询;

3、联合查询

MySQL的联合查询:把两个或多个查询语句的结果合并成一个结果进行输出;

语法:SELECT clauase UNION SELECT clause UNION ...

二、应用举例

1、列举数据库表的内容

MariaDB [hellodb]> SHOW TABLES;+-------------------+| Tables_in_hellodb |+-------------------+| classes           || coc               || courses           || scores            || students          || teachers          || toc               |+-------------------+7 rows in set (0.00 sec)
MariaDB [hellodb]> SELECT * FROM classes;+---------+-----------------+----------+| ClassID | Class           | NumOfStu |+---------+-----------------+----------+|       1 | Shaolin Pai     |       10 ||       2 | Emei Pai        |        7 ||       3 | QingCheng Pai   |       11 ||       4 | Wudang Pai      |       12 ||       5 | Riyue Shenjiao  |       31 ||       6 | Lianshan Pai    |       27 ||       7 | Ming Jiao       |       27 ||       8 | Xiaoyao Pai     |       15 ||       9 | Jiuyin Zhenjing |       22 |+---------+-----------------+----------+9 rows in set (0.00 sec)
MariaDB [hellodb]> SELECT * FROM coc;+----+---------+----------+| ID | ClassID | CourseID |+----+---------+----------+|  1 |       1 |        2 ||  2 |       1 |        5 ||  3 |       2 |        2 ||  4 |       2 |        6 ||  5 |       3 |        1 ||  6 |       3 |        7 ||  7 |       4 |        5 ||  8 |       4 |        2 ||  9 |       5 |        1 || 10 |       5 |        9 || 11 |       6 |        3 || 12 |       6 |        4 || 13 |       7 |        4 || 14 |       7 |        3 |+----+---------+----------+14 rows in set (0.00 sec)
MariaDB [hellodb]> SELECT * FROM courses;+----------+----------------+| CourseID | Course         |+----------+----------------+|        1 | Hamo Gong      ||        2 | Kuihua Baodian ||        3 | Jinshe Jianfa  ||        4 | Taiji Quan     ||        5 | Daiyu Zanghua  ||        6 | Weituo Zhang   ||        7 | Dagou Bangfa   |+----------+----------------+7 rows in set (0.00 sec)
MariaDB [hellodb]> SELECT * FROM scores;+----+-------+----------+-------+| ID | StuID | CourseID | Score |+----+-------+----------+-------+|  1 |     1 |        2 |    77 ||  2 |     1 |        6 |    93 ||  3 |     2 |        2 |    47 ||  4 |     2 |        5 |    97 ||  5 |     3 |        2 |    88 ||  6 |     3 |        6 |    75 ||  7 |     4 |        5 |    71 ||  8 |     4 |        2 |    89 ||  9 |     5 |        1 |    39 || 10 |     5 |        7 |    63 || 11 |     6 |        1 |    96 || 12 |     7 |        1 |    86 || 13 |     7 |        7 |    83 || 14 |     8 |        4 |    57 || 15 |     8 |        3 |    93 |+----+-------+----------+-------+15 rows in set (0.00 sec)
MariaDB [hellodb]> SELECT * FROM students;+-------+---------------+-----+--------+---------+-----------+| StuID | Name          | Age | Gender | ClassID | TeacherID |+-------+---------------+-----+--------+---------+-----------+|     1 | Shi Zhongyu   |  22 | M      |       2 |         3 ||     2 | Shi Potian    |  22 | M      |       1 |         7 ||     3 | Xie Yanke     |  53 | M      |       2 |        16 ||     4 | Ding Dian     |  32 | M      |       4 |         4 ||     5 | Yu Yutong     |  26 | M      |       3 |         1 ||     6 | Shi Qing      |  46 | M      |       5 |      NULL ||     7 | Xi Ren        |  19 | F      |       3 |      NULL ||     8 | Lin Daiyu     |  17 | F      |       7 |      NULL ||     9 | Ren Yingying  |  20 | F      |       6 |      NULL ||    10 | Yue Lingshan  |  19 | F      |       3 |      NULL ||    11 | Yuan Chengzhi |  23 | M      |       6 |      NULL ||    12 | Wen Qingqing  |  19 | F      |       1 |      NULL ||    13 | Tian Boguang  |  33 | M      |       2 |      NULL ||    14 | Lu Wushuang   |  17 | F      |       3 |      NULL ||    15 | Duan Yu       |  19 | M      |       4 |      NULL ||    16 | Xu Zhu        |  21 | M      |       1 |      NULL ||    17 | Lin Chong     |  25 | M      |       4 |      NULL ||    18 | Hua Rong      |  23 | M      |       7 |      NULL ||    19 | Xue Baochai   |  18 | F      |       6 |      NULL ||    20 | Diao Chan     |  19 | F      |       7 |      NULL ||    21 | Huang Yueying |  22 | F      |       6 |      NULL ||    22 | Xiao Qiao     |  20 | F      |       1 |      NULL ||    23 | Ma Chao       |  23 | M      |       4 |      NULL ||    24 | Xu Xian       |  27 | M      |    NULL |      NULL ||    25 | Sun Dasheng   | 100 | M      |    NULL |      NULL ||    26 | Zhao Ming     |  24 | F      |       8 |        11 ||    27 | Zhang Wuji    |  25 | M      |       9 |         2 |+-------+---------------+-----+--------+---------+-----------+27 rows in set (0.00 sec)
MariaDB [hellodb]> SELECT * FROM teachers;+-----+---------------+-----+--------+| TID | Name          | Age | Gender |+-----+---------------+-----+--------+|   1 | Song Jiang    |  45 | M      ||   2 | Zhang Sanfeng |  94 | M      ||   3 | Miejue Shitai |  77 | F      ||   4 | Lin Chaoying  |  93 | F      |+-----+---------------+-----+--------+4 rows in set (0.00 sec)

2、应用举例

交叉联合应用:

MariaDB [hellodb]> SELECT * FROM students,classes;

此语句会输出students表中的列数与classes表中列数的乘积个行,所以效率极低。

自然连接的应用:

MariaDB [hellodb]> SELECT * FROM students,classes WHERE students.ClassID = classes.ClassID;

这种连接会根据两表的等值进行输出,而一旦在比较的等值项目中出现NULL,则该行就不会输出。

通过等值比较输出指定的内容:

MariaDB [hellodb]> SELECT students.Name,classes.Class FROM students,classes WHERE students.ClassID=classes.ClassID;

通过表别名的方法来实现上例的查询:

MariaDB [hellodb]> SELECT s.Name,c.Class FROM students AS s,classes AS c WHERE s.ClassID=c.ClassID;

由于在students表中有两个学生的班级好为NULL,所以使用上面的查询并不能查出结果,若想能将其查询出来,就可以使用左外连接查询,或者右外连接查询:

MariaDB [hellodb]> SELECT s.Name,c.Class FROM students AS s LEFT JOIN classes AS c ON s.ClassID =c.ClassID;MariaDB [hellodb]> SELECT c.Class,s.Name FROM classes AS c RIGHT JOIN students AS s ON s.ClassID =c.ClassID;

查询前五名学生所学的课程并以升序的方式显示:

MariaDB [hellodb]>  SELECT StuID,Name,Course FROM students AS s,courses AS c,coc WHERE s.ClassID=coc.ClassID AND coc.CourseID=c.CourseID AND s.StuID <= 5 ORDER BY StuID;+-------+-------------+----------------+| StuID | Name        | Course         |+-------+-------------+----------------+|     1 | Shi Zhongyu | Kuihua Baodian ||     1 | Shi Zhongyu | Weituo Zhang   ||     2 | Shi Potian  | Daiyu Zanghua  ||     2 | Shi Potian  | Kuihua Baodian ||     3 | Xie Yanke   | Weituo Zhang   ||     3 | Xie Yanke   | Kuihua Baodian ||     4 | Ding Dian   | Daiyu Zanghua  ||     4 | Ding Dian   | Kuihua Baodian ||     5 | Yu Yutong   | Dagou Bangfa   ||     5 | Yu Yutong   | Hamo Gong      |+-------+-------------+----------------+10 rows in set (0.00 sec)

将上例的输出结果在加上成绩:

MariaDB [hellodb]> SELECT s.StuID,s.Name,c.Course,sc.Score FROM students AS s,courses AS c,coc,scores AS sc WHERE s.ClassID=coc.ClassID AND coc.CourseID=c.CourseID AND s.StuID <= 5 AND s.StuID=sc.StuID AND coc.CourseID=sc.CourseID ORDER BY s.StuID;+-------+-------------+----------------+-------+| StuID | Name        | Course         | Score |+-------+-------------+----------------+-------+|     1 | Shi Zhongyu | Weituo Zhang   |    93 ||     1 | Shi Zhongyu | Kuihua Baodian |    77 ||     2 | Shi Potian  | Daiyu Zanghua  |    97 ||     2 | Shi Potian  | Kuihua Baodian |    47 ||     3 | Xie Yanke   | Weituo Zhang   |    75 ||     3 | Xie Yanke   | Kuihua Baodian |    88 ||     4 | Ding Dian   | Kuihua Baodian |    89 ||     4 | Ding Dian   | Daiyu Zanghua  |    71 ||     5 | Yu Yutong   | Hamo Gong      |    39 ||     5 | Yu Yutong   | Dagou Bangfa   |    63 |+-------+-------------+----------------+-------+10 rows in set (0.00 sec)

前8位同学每位同学自己两门课的平均成绩,并按降序排列:

MariaDB [hellodb]> SELECT Name,AVG(Score) FROM students AS s,courses AS c,coc,scores AS sc WHERE s.ClassID=coc.ClassID AND coc.CourseID=c.CourseID AND s.StuID <=8 AND s.StuID=sc.StuID AND coc.CourseID=sc.CourseID GROUP BY Name ORDER BY AVG(Score)DESC;+-------------+------------+| Name        | AVG(Score) |+-------------+------------+| Shi Qing    |    96.0000 || Shi Zhongyu |    85.0000 || Xi Ren      |    84.5000 || Xie Yanke   |    81.5000 || Ding Dian   |    80.0000 || Lin Daiyu   |    75.0000 || Shi Potian  |    72.0000 || Yu Yutong   |    51.0000 |+-------------+------------+8 rows in set (0.00 sec)

显示其年龄大于平均年龄的同学的名字:

MariaDB [hellodb]> SELECT Name,Age FROM students WHERE Age >(SELECT AVG(Age) FROM students);+--------------+-----+| Name         | Age |+--------------+-----+| Xie Yanke    |  53 || Ding Dian    |  32 || Shi Qing     |  46 || Tian Boguang |  33 || Sun Dasheng  | 100 |+--------------+-----+5 rows in set (0.00 sec)

显示所有课程及其班级ID:

MariaDB [hellodb]> SELECT Class,coc.ClassID FROM classes LEFT JOIN coc ON classes.ClassID = coc.Classid;+-----------------+---------+| Class           | ClassID |+-----------------+---------+| Shaolin Pai     |       1 || Shaolin Pai     |       1 || Emei Pai        |       2 || Emei Pai        |       2 || QingCheng Pai   |       3 || QingCheng Pai   |       3 || Wudang Pai      |       4 || Wudang Pai      |       4 || Riyue Shenjiao  |       5 || Riyue Shenjiao  |       5 || Lianshan Pai    |       6 || Lianshan Pai    |       6 || Ming Jiao       |       7 || Ming Jiao       |       7 || Xiaoyao Pai     |    NULL || Jiuyin Zhenjing |    NULL |+-----------------+---------+16 rows in set (0.00 sec)

显示没有开课的班级:

MariaDB [hellodb]> SELECT Class,coc.ClassID FROM classes LEFT JOIN coc ON classes.ClassID = coc.ClassID WHERE coc.ClassID IS NULL;+-----------------+---------+| Class           | ClassID |+-----------------+---------+| Xiaoyao Pai     |    NULL || Jiuyin Zhenjing |    NULL |+-----------------+---------+2 rows in set (0.00 sec)

显示没有开课的班级的同学:

MariaDB [hellodb]> SELECT Name FROM students WHERE ClassID IN(SELECT classes.ClassID FROM classes LEFT JOIN coc ON classes.ClassID = coc.Classid WHERE coc.ClassID IS NULL);+------------+| Name       |+------------+| Zhao Ming  || Zhang Wuji |+------------+2 rows in set (0.00 sec)

自连接的使用,查看学生及其老师:

MariaDB [hellodb]> SELECT t.Name,s.Name FROM students AS s,students AS t WHERE t.TeacherID=s.StuID;+-------------+---------------+| Name        | Name          |+-------------+---------------+| Shi Zhongyu | Xie Yanke     || Shi Potian  | Xi Ren        || Xie Yanke   | Xu Zhu        || Ding Dian   | Ding Dian     || Yu Yutong   | Shi Zhongyu   || Zhao Ming   | Yuan Chengzhi || Zhang Wuji  | Shi Potian    |+-------------+---------------+7 rows in set (0.00 sec)

三、MySQL视图

   视图就是存储下来的SELECT语句;

举例:

MariaDB [hellodb]> CREATE VIEW stu AS SELECT StuID,Name,Age,Gender FROM students;Query OK, 0 rows affected (0.12 sec)MariaDB [hellodb]> SHOW TABLE STATUS LIKE 'stu'\G;*************************** 1. row ***************************           Name: stu         Engine: NULL        Version: NULL     Row_format: NULL           Rows: NULL Avg_row_length: NULL    Data_length: NULLMax_data_length: NULL   Index_length: NULL      Data_free: NULL Auto_increment: NULL    Create_time: NULL    Update_time: NULL     Check_time: NULL      Collation: NULL       Checksum: NULL Create_options: NULL        Comment: VIEW1 row in set (0.00 sec)MariaDB [hellodb]> DESC stu;+--------+---------------------+------+-----+---------+-------+| Field  | Type                | Null | Key | Default | Extra |+--------+---------------------+------+-----+---------+-------+| StuID  | int(10) unsigned    | NO   |     | 0       |       || Name   | varchar(50)         | NO   |     | NULL    |       || Age    | tinyint(3) unsigned | NO   |     | NULL    |       || Gender | enum('F','M')       | NO   |     | NULL    |       |+--------+---------------------+------+-----+---------+-------+4 rows in set (0.07 sec)

四、INSERT INTO、UPDATE、DELETE命令简单介绍

1、INSERT INTO:插入数据

  • 第一种使用方法: 

    INSERT INTO tb_name [(col1,col2,....)]{values|value}(val1,val2,...)[,(val21,val22,....),....]

  • 第二种使用方法: 

     INSERT INTO tb_name set col_name=val1,col2=val2,....

  • 第三种使用方法:(将一个表中的数据插入到另外一张表中) 

     INSERT INTO tb_name SELECT clause

2、REPLACE

   说明:此命令与INSERT INTO 使用的性质一样,即替换表中数据,但是其除了插入数据这一功能外还有当新插入的数据与表中的主键或唯一索引定义的数据相同会替换老的行 。

3、UPDATE:更新数据 

语法: UPDATE [LOW_PRIORITY] [IGNORE] table_reference

            SET col_name1=val1 [, col_name2={val2] ...

            [WHERE where_condition]

            [ORDER BY ...]

            [LIMIT row_count]

   注意:UPDATE通常情况下,后面必须要使用WHERE字句,或者使用LIMIT限制要修改的行数 ,不然后将表中所有数据给更新了,为避免在使用中出现此种状况,建议在登录系统时后面带有--safe-updates选项,意思为:当在执行UPDATE、DELETE语句时后面忘记带有限制条件是系统是拒绝执行的,所以在登录是建议带上此选项。   

4、DELETE:删除数据

语法:DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name 

            [WHERE where_condition]

            [ORDER BY ...]

            [LIMIT row_count]

   使用建议:在删除一张表时可以使用DELETE语句,但是若表中有自动增长的字段时就不会将其清零,这样就建议使用TRUNCATE tb_name来重置表的所有内容,这样做就会把自动增长字段给重置。同时还有一种方法就是,先复制表的结构,然后把表给DROP掉,这种方法也可行。