[MySQL]_5.MySQL joint query

Table of contents

1. Cartesian product

2. Inner join

2.1 Example 1: Query Xu Xian's grades

2.2 Example 2: Query the total grades of all students and their personal information

2.3 Example 3: Query the subjects and grades of all students, and the personal information of students

3. Outer join

3.1 Case 1: One-to-one correspondence between two table data

3.2 Case 2: The two table data are not one-to-one correspondence

4. Self-join

5. Subqueries (nested queries)

5.1 Subquery Classification

5.2 Single row subquery example 1: Query classmates who do not want to graduate

5.3 Multi-line subquery example 2: Query information grades of Chinese or English courses

6. Combine queries

6.1 Example 1: Query courses with id=3 or names in English


Joint query is also called multi-table query, which combines multiple tables together for query;

1. Cartesian product

The Cartesian product is the basis of the joint query. The Cartesian product is actually a permutation and combination, which arranges and combines the records of the two tables as much as possible into n situations:

Taking two tables: class table and student table as an example, calculate the Cartesian product of these two tables:

The Cartesian product is to get a larger table, the number of columns is the sum of the two table columns, and the number of rows is the product of the two table column numbers;

Try to create the following tables under the testdemo1 database:

mysql> show tables;
+---------------------+
| Tables_in_testdemo1 |
+---------------------+
| classes             |
| course              |
| score               |
| student             |
+---------------------+
4 rows in set (0.00 sec)

 The structure and content of the table are as follows:

(1) student table:

mysql> desc student;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| sn         | varchar(20) | YES  |     | NULL    |                |
| name       | varchar(20) | YES  |     | NULL    |                |
| qq_mail    | varchar(20) | YES  |     | NULL    |                |
| classes_id | int(11)     | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> 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)

(2) classes table:

mysql> desc classes;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20)  | YES  |     | NULL    |                |
| desc  | varchar(100) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

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

(3) course table:

mysql> desc course;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

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

(4) score table: 

mysql> desc score;
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| score      | decimal(3,1) | YES  |     | NULL    |       |
| student_id | int(11)      | YES  |     | NULL    |       |
| course_id  | int(11)      | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> 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)

In this database, there are four tables and three entities: students, classes, and courses;

Among them, students and classes have a one-to-many relationship, students and courses have a many-to-many relationship (the grade table is an association table), and there is no direct relationship between classes and courses;

2. Inner join

There are two syntaxes for inner joins:

The first:

select [列名],[列名]... form [表1],[表2] where 条件;

The second type:

select [列名],[列名] from [表1] join [表2] on 条件;

2.1 Example 1: Query Xu Xian's grades

("Xu Xian" is the name in the student table, and "achievement" is in the score table, which are located in different tables and need to be queried)

Perform Cartesian product of the student table and the score table --> delete invalid data --> filter by Xu Xian's name --> streamline the results if necessary;

(1) Calculate the Cartesian product of the student table and the score table: 

mysql> select* from student,score;

(2) Delete invalid data according to whether the associated columns of the two tables correspond: 

mysql> select* from student, score where id = student_id;

Note: When the associated column name of the joint query has the same name, you can use the table name. column name to specify , that is, the above SQL command can also be written as:

mysql> select* from student, score where student.id =  score.student_id;

In actual development, it is recommended to use this writing method to avoid confusion when there are multiple tables and multiple columns; 

(3) According to the name, filter out the grades of Xu Xian:

mysql> select* from student, score where student.id=score.student_id and student.name = "许仙";

At this time, the query result is:

+----+-------+------+---------------+------------+-------+------------+-----------+
| 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) Streamline the query results, the query instructions and the final query results are:

mysql> select student.name, score.course_id, score.score from student, score
    -> where student.id = score.student_id and student.name = "许仙";
+------+-----------+-------+
| name | course_id | score |
+------+-----------+-------+
| 许仙 |         1 |  67.0 |
| 许仙 |         3 |  23.0 |
| 许仙 |         5 |  56.0 |
| 许仙 |         6 |  72.0 |
+------+-----------+-------+
4 rows in set (0.00 sec)

Note: There are two ways to calculate the Cartesian product:

The first:

select* from [表名],[表名] where [条件];

 The second type:

select* from [表名] join [表名] on [条件]; 

Therefore, the above SQL statement can also be written as:

mysql> select student.name, score.course_id, score.score from
    -> student join score
    -> on student.id = score.student_id and student.name="许仙";

2.2 Example 2: Query the total grades of all students and their personal information

(The query information is related to the student table and grade table)

Calculate the Cartesian product of the student table and the score table --> delete invalid information according to the joint column student id --> group by student name or id and sum the score according to the grouping situation

(1) Calculate the Cartesian product of the student table and the score table and delete invalid information:

mysql> select* from student,score where student.id = score.student_id;

(2) Group according to the student id, and use the aggregate function sum to aggregate and calculate the total score according to the group:

mysql> select student.name, sum(score.score)from student,score where student.id = score.student_id group by 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.00 sec)

2.3 Example 3: Query the subjects and grades of all students, and the personal information of students

 (The name of the classmate is in the student table, the subject information is in the course table, and the scores of each subject are in the score table)

mysql> select student.name, course.name, score.score
    -> from student, course, score
    -> where student.id = score.student_id
    -> and score.course_id = course.id;
+------------+--------------+-------+
| name       | name         | score |
+------------+--------------+-------+
| 黑旋风李逵 | Java         |  70.5 |
| 黑旋风李逵 | 计算机原理   |  98.5 |
| 黑旋风李逵 | 高阶数学     |  33.0 |
| 黑旋风李逵 | 英文         |  98.0 |
| 菩提老祖   | Java         |  60.0 |
| 菩提老祖   | 高阶数学     |  59.5 |
| 白素贞     | Java         |  33.0 |
| 白素贞     | 计算机原理   |  68.0 |
| 白素贞     | 高阶数学     |  99.0 |
| 许仙       | Java         |  67.0 |
| 许仙       | 计算机原理   |  23.0 |
| 许仙       | 高阶数学     |  56.0 |
| 许仙       | 英文         |  72.0 |
| 不想毕业   | Java         |  81.0 |
| 不想毕业   | 高阶数学     |  37.0 |
| 好好说话   | 中国传统文化 |  56.0 |
| 好好说话   | 语文         |  43.0 |
| 好好说话   | 英文         |  79.0 |
| tellme     | 中国传统文化 |  80.0 |
| tellme     | 英文         |  92.0 |
+------------+--------------+-------+
20 rows in set (0.00 sec)

3. Outer join

Both inner join and outer join are Cartesian product calculations, but there are still differences in details:

3.1 Case 1: One-to-one correspondence between two table data

Based on the following databases and tables:

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

mysql> select* from score;
+------------+-------+
| student_id | score |
+------------+-------+
|          1 |    90 |
|          2 |    80 |
|          3 |    70 |
+------------+-------+
3 rows in set (0.00 sec)

The inner join instruction is:

mysql> select name, score from student join score on student.id = score.student_id;

The left outer join instruction is:

mysql> select name, score from student left join score on student.id = score.student_id;

The right outer join instruction is:

mysql> select name, score from student left join score on student.id = score.student_id;

 The query results of the above three commands are:

+------+-------+
| name | score |
+------+-------+
| 张三 |    90 |
| 李四 |    80 |
| 王五 |    70 |
+------+-------+

That is: when the data of the two tables are in one-to-one correspondence (that is, the records of the two tables are reflected in each other), the query results of the inner join and the outer join are the same ;

3.2 Case 2: The two table data are not one-to-one correspondence

Based on the following database and tables:

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

mysql> select* from score;
+------------+-------+
| student_id | score |
+------------+-------+
|          1 |    90 |
|          2 |    80 |
|          4 |    70 |
+------------+-------+
3 rows in set (0.00 sec)

The inner join command and query result are:

mysql> select name, score from student join score on student.id = score.student_id;
+------+-------+
| name | score |
+------+-------+
| 张三 |    90 |
| 李四 |    80 |
+------+-------+
2 rows in set (0.00 sec)

The left outer join instruction and query result are:

mysql> select name, score from student left join score on student.id = score.student_id;
+------+-------+
| name | score |
+------+-------+
| 张三 |    90 |
| 李四 |    80 |
| 王五 |  NULL |
+------+-------+
3 rows in set (0.00 sec)

The right outer join instruction and the query result are:

mysql> select name, score from student right join score on student.id = score.student_id;
+------+-------+
| name | score |
+------+-------+
| 张三 |    90 |
| 李四 |    80 |
| NULL |    70 |
+------+-------+
3 rows in set (0.00 sec)

That is: when the data in the two tables is not in one-to-one correspondence, the inner connection only displays the data reflected in the two tables ;

Note: (1) When the data in the two tables is not in one-to-one correspondence, when performing an outer join, the left outer join is based on the left table, and if there is no corresponding data in the right table , it will be filled with null values ;

The right outer join is based on the right table, and the left table has no corresponding data and is filled with null values;

(2) The join on statement for multiple tables is:

select* form table 1 join table 2 on condition 1 join table 4 on condition 2, such as:

mysql> select* from student join score on student.id = score.student_id
    -> join course on course.id =score.course_id;

But each join on statement only calculates the Cartesian product of the two tables; 

4. Self-join

        Self-join is the Cartesian product of the table itself and itself. Conditional query in SQL is to specify a certain column or multiple columns to perform relational operations, and row-to-row operations cannot be performed. In some cases, it is necessary To perform relational operations between rows, you need to use self-join. The essence of self-join is to convert rows into columns ;

Example: Display all grade information of "course id 3" higher than "course id 1":

(Grade information is in the score table)

(1) Perform self-connection on score (alias for Cartesian product) and delete invalid information:

mysql> select* from score as s1, score as s2 where s1.student_id = s2.student_id;

(2) Select the course with id=1 in the first column and the course with id=3 in the second column:

mysql> select* from score as s1, score as s2
    -> where s1.student_id = s2.student_id
    -> and s1.course_id = 1
    -> and s2.course_id = 3;

(The result means that three students have taken these two courses at the same time)

(3) Add the condition that the score in the left column is less than the score in the right column, and the SQL command and query result are:

mysql> select* from score as s1,score as s2
    -> where s1.student_id = s2.student_id
    -> and s1.course_id = 1
    -> and s2.course_id = 3
    -> and s1.score < s2.score;
+-------+------------+-----------+-------+------------+-----------+
| score | student_id | course_id | score | student_id | course_id |
+-------+------------+-----------+-------+------------+-----------+
|  70.5 |          1 |         1 |  98.5 |          1 |         3 |
|  33.0 |          3 |         1 |  68.0 |          3 |         3 |
+-------+------------+-----------+-------+------------+-----------+
2 rows in set (0.00 sec)

Note: (1) Self-connection cannot be performed directly:

mysql> select* from score,score;
ERROR 1066 (42000): Not unique table/alias: 'score'

Two aliases need to be specified for the table, namely:

mysql> select* from score as s1, score as s2;

5. Subqueries (nested queries)

A subquery is a select statement embedded in other SQL statements, that is, multiple query statements are combined into one statement;

5.1 Subquery Classification

(1) Single row subquery: the query result has only one record;

(2) Multi-line subquery: the query result is multiple records;

5.2 Single row subquery example 1: Query classmates who do not want to graduate

(1) Step-by-step query SQL commands and query results are:

mysql> select classes_id from student where name="不想毕业";
+------------+
| classes_id |
+------------+
|          1 |
+------------+
1 row in set (0.00 sec)

mysql> select name from student where classes_id =1;
+------------+
| name       |
+------------+
| 黑旋风李逵 |
| 菩提老祖   |
| 白素贞     |
| 许仙       |
| 不想毕业   |
+------------+
5 rows in set (0.00 sec)

(2) The subquery SQL command and query result are:

mysql> select name from student where classes_id = (select classes_id from student where name="不想毕业");
+------------+
| name       |
+------------+
| 黑旋风李逵 |
| 菩提老祖   |
| 白素贞     |
| 许仙       |
| 不想毕业   |
+------------+
5 rows in set (0.00 sec)

That is to replace a certain value of the conditional query with a select query statement;

5.3 Multi-line subquery example 2: Query information grades of Chinese or English courses

First query the course id of the two courses, and then query in the score table according to the course_id;

(1) Step-by-step query SQL commands and query results are:

mysql> select id from course where name="语文" or name="英文";
+----+
| id |
+----+
|  4 |
|  6 |
+----+
2 rows in set (0.00 sec)

mysql> select* from score where course_id in(4,6);
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+
5 rows in set (0.00 sec)

(2) The subquery SQL command and query result are:

mysql> select* from score where course_id in(select id from course where name="语文" or name="英文");
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|  98.0 |          1 |         6 |
|  72.0 |          4 |         6 |
|  43.0 |          6 |         4 |
|  79.0 |          6 |         6 |
|  92.0 |          7 |         6 |
+-------+------------+-----------+
5 rows in set (0.00 sec)

6. Combine queries

Combined query is to combine the results of two query statements together;

6.1 Example 1: Query courses with id=3 or names in English

(1) Use logical OR to implement the query:

mysql> select* from course where id<3 or name="英文";
+----+--------------+
| id | name         |
+----+--------------+
|  1 | Java         |
|  2 | 中国传统文化 |
|  6 | 英文         |
+----+--------------+
3 rows in set (0.00 sec)

(2) Use the union keyword for combined queries:

mysql> select* from course where id<3 union select* from course where name="英文";
+----+--------------+
| id | name         |
+----+--------------+
|  1 | Java         |
|  2 | 中国传统文化 |
|  6 | 英文         |
+----+--------------+
3 rows in set (0.00 sec)

Note: (1) The difference between union and logical or:

Logical or can only combine the query results of one table, but union can combine the query results of multiple tables (the columns requiring multiple results must correspond) ;

(2) The difference between union and union all:

When using the union keyword to merge multiple query results, it will automatically deduplicate, but unionall will not deduplicate ;

Guess you like

Origin blog.csdn.net/m0_63299495/article/details/131857259
Recommended