[MySQL joint query] easy data association

1. Joint query

Joint query is also called multi-table query, and its basic execution process is Cartesian product

1.1 Understanding Cartesian product

So what is a Cartesian product?

Answer: Cartesian product is to put two tables together for calculation, take out each row of the first table and connect with each row of the second table to get a new row.

Example Cartesian product:

Suppose we now have two tables, the student information table and the class information table

Now we perform Cartesian product operation on these two tables:

The Cartesian product is equivalent to the multiplication operation, the number of columns is the sum of the columns of the two tables, and the number of rows is the product of the rows of the two tables

Note: Most of the results generated after Cartesian product execution are invalid, at this time we can use conditions to filter

1.2 Cartesian product for multi-table query

Next, let's try how to perform the Cartesian product operation:

First create two tables, namely the above-mentioned student information table and class information table. After creating the two tables, add the content in the above table to them

select * from student;
+----+------+---------+
| id | name | classid |
+----+------+---------+
|  1 | 张三 |       1 |
|  2 | 李四 |       2 |
|  3 | 王五 |       1 |
+----+------+---------+
select * from class;
+---------+-----------+
| classid | classname |
+---------+-----------+
|       1 | 舞蹈班    |
|       2 | 跆拳道班  |
+---------+-----------+

Then perform Cartesian product operation on these two tables

select * from student,class;
+----+------+---------+---------+-----------+
| id | name | classid | classid | classname |
+----+------+---------+---------+-----------+
|  1 | 张三 |       1 |       1 | 舞蹈班    |
|  1 | 张三 |       1 |       2 | 跆拳道班  |
|  2 | 李四 |       2 |       1 | 舞蹈班    |
|  2 | 李四 |       2 |       2 | 跆拳道班  |
|  3 | 王五 |       1 |       1 | 舞蹈班    |
|  3 | 王五 |       1 |       2 | 跆拳道班  |
+----+------+---------+---------+-----------+

Most of the results generated after the execution of the above-mentioned Cartesian product are invalid, at this time we can use conditions to filter

When the classid in the student table is equal to the classid in the class table, this piece of data is valid data

select * from student,class where classid = classid;
ERROR 1052 (23000): Column 'classid' in where clause is ambiguous

If you use classid = classid directly, it will report an error, because it cannot tell which classid is compared with which classid

select * from student,class where student.classid = class.classid;
+----+------+---------+---------+-----------+
| id | name | classid | classid | classname |
+----+------+---------+---------+-----------+
|  1 | 张三 |       1 |       1 | 舞蹈班    |
|  2 | 李四 |       2 |       2 | 跆拳道班  |
|  3 | 王五 |       1 |       1 | 舞蹈班    |
+----+------+---------+---------+-----------+

Then you can use the table name. Column name method to distinguish

Note: In addition to adding connection conditions, multi-table queries can also add other conditions

For multi-table query, use from multiple tables and separate them with commas to connect multiple tables. You can also use join on to connect, or inner join on

join on implements multi-table query:

select * from student join class on student.classid = class.classid;
+----+------+---------+---------+-----------+
| id | name | classid | classid | classname |
+----+------+---------+---------+-----------+
|  1 | 张三 |       1 |       1 | 舞蹈班    |
|  2 | 李四 |       2 |       2 | 跆拳道班  |
|  3 | 王五 |       1 |       1 | 舞蹈班    |
+----+------+---------+---------+-----------+

join connects two tables, and on is followed by the connection condition

Inner join on implements multi-table query:

select * from student inner join class on student.classid = class.classid;
+----+------+---------+---------+-----------+
| id | name | classid | classid | classname |
+----+------+---------+---------+-----------+
|  1 | 张三 |       1 |       1 | 舞蹈班    |
|  2 | 李四 |       2 |       2 | 跆拳道班  |
|  3 | 王五 |       1 |       1 | 舞蹈班    |
+----+------+---------+---------+-----------+

Inner join on is actually the same as join on, so I won’t explain too much here

The main difference between from multiple tables and join on:

  • From multiple tables can only achieve inner joins

  • join on can realize both inner join and outer join

1.3 Inner join and outer join

The main difference between inner join and outer join:

  • When the data in the two tables to be connected is in one-to-one correspondence, there is actually no difference between the inner join and the outer join.

  • When the data in the two tables to be joined is not one-to-one, there is a difference between inner join and outer join.

1.3.1 One-to-one correspondence between two tables

Now there are two tables, the student table and the score table:

select * from student;
+----+------+
| id | name |
+----+------+
|  1 | 张三 |
|  2 | 李四 |
|  3 | 王五 |
+----+------+
select * from scoretable;
+-----------+-------+
| studentId | score |
+-----------+-------+
|         1 |    97 |
|         2 |    86 |
|         3 |    73 |
+-----------+-------+

There is a one-to-one correspondence between id and studentId, and there is no difference between all inner connections and outer connections

Inner join:

select * from student,scoreTable where student.id = scoretable.studentId;
+----+------+-----------+-------+
| id | name | studentId | score |
+----+------+-----------+-------+
|  1 | 张三 |         1 |    97 |
|  2 | 李四 |         2 |    86 |
|  3 | 王五 |         3 |    73 |
+----+------+-----------+-------+

Outer join:

select * from student join scoreTable on student.id = scoretable.studentId;
+----+------+-----------+-------+
| id | name | studentId | score |
+----+------+-----------+-------+
|  1 | 张三 |         1 |    97 |
|  2 | 李四 |         2 |    86 |
|  3 | 王五 |         3 |    73 |
+----+------+-----------+-------+

1.3.2 There is no one-to-one correspondence between the two tables

Now there are two tables, the student table and the score table:

select * from student;
+----+------+
| id | name |
+----+------+
|  1 | 张三 |
|  2 | 李四 |
|  3 | 王五 |
+----+------+
select * from scoretable;
+-----------+-------+
| studentId | score |
+-----------+-------+
|         1 |    97 |
|         2 |    86 |
|         6 |    73 |
+-----------+-------+

Now we can see that the student with id 3 has no corresponding studentId in scoretable

Inner join:

select * from student,scoreTable where student.id = scoretable.studentId;
+----+------+-----------+-------+
| id | name | studentId | score |
+----+------+-----------+-------+
|  1 | 张三 |         1 |    97 |
|  2 | 李四 |         2 |    86 |
+----+------+-----------+-------+

When performing an inner connection, because the id in the student is 3 and the studentId in the scoretable is 6 does not match, it is screened out and not queried

Outer join:

When the two tables are not in one-to-one correspondence, outer joins can be divided into left outer joins and right outer joins

  • Left outer connection: left join on

select * from student left join scoreTable on student.id = scoretable.studentId;
+----+------+-----------+-------+
| id | name | studentId | score |
+----+------+-----------+-------+
|  1 | 张三 |         1 |    97 |
|  2 | 李四 |         2 |    86 |
|  3 | 王五 |      NULL |  NULL |
+----+------+-----------+-------+

The left outer join will display the results of the left table as much as possible. If there is no corresponding record in the right table, fill it with NULL

  • Right outer join: right join on

select * from student right join scoreTable on student.id = scoretable.studentId;
+------+------+-----------+-------+
| id   | name | studentId | score |
+------+------+-----------+-------+
|    1 | 张三 |         1 |    97 |
|    2 | 李四 |         2 |    86 |
| NULL | NULL |         6 |    73 |
+------+------+-----------+-------+

The right outer join will display the results of the right table as much as possible. If there is no corresponding record in the left table, fill it with NULL

1.4 Self-join

Self-join: Cartesian product of itself and itself

Self-join usage scenario: When rows are compared with rows, self-joins can be used to convert rows into columns for comparison

Now there are two tables, scoretable and course

scoretable table:

select * from scoretable;
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|    70 |          1 |         1 |
|    96 |          1 |         2 |
|    97 |          1 |         3 |
|    80 |          2 |         1 |
|    92 |          2 |         2 |
|    86 |          2 |         3 |
|    91 |          3 |         1 |
|    76 |          3 |         2 |
|    77 |          3 |         3 |
+-------+------------+-----------+

course table:

select * from course;
+----+------+
| id | name |
+----+------+
|  1 | 语文 |
|  2 | 数学 |
|  3 | 英语 |
+----+------+

Now we want to check which students have lower Chinese scores than English scores

First self-join, converting rows into columns:

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

Connect yourself with yourself, the name cannot be repeated

The table name cannot be repeated, so how can it be self-connected?

Answer: You can create an alias, which can not only align columns, but also align tables

select * from scoretable as s1,scoretable as s2;

A large amount of invalid data will be generated when self-connecting permutations and combinations, so you need to specify the connection conditions

Specify the connection conditions to filter out valid data:

select * from scoretable as s1,scoretable as s2 
where s1.student_id = s2.student_id;

When self-connecting, only when the student_id is equal, it indicates valid data

Add conditions to query the Chinese scores in the left table and the English scores in the right table:

After the valid results are checked out, you need to add conditions to check the Chinese scores on the left and the English scores on the right

select * from scoretable as s1,scoretable as s2 
where s1.student_id = s2.student_id 
and s1.course_id = 1 and s2.course_id = 3;
+-------+------------+-----------+-------+------------+-----------+
| score | student_id | course_id | score | student_id | course_id |
+-------+------------+-----------+-------+------------+-----------+
|    70 |          1 |         1 |    97 |          1 |         3 |
|    80 |          2 |         1 |    86 |          2 |         3 |
|    91 |          3 |         1 |    77 |          3 |         3 |
+-------+------------+-----------+-------+------------+-----------+

In this way, the Chinese scores on the left are queried, and the English scores on the right are queried.

Add conditions to query the students whose Chinese scores are lower than their English scores:

The next step is to check which students have lower Chinese scores than English scores.

select * from scoretable as s1,scoretable 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 |          1 |         1 |    97 |          1 |         3 |
|    80 |          2 |         1 |    86 |          2 |         3 |
+-------+------------+-----------+-------+------------+-----------+
2 rows in set (0.00 sec)

In this way, the information of students whose Chinese scores are lower than their English scores can be queried.

1.5 Subqueries

Subquery: Combine multiple SQLs into one

In actual development, subqueries should be used with caution. Because subqueries may construct very complex, very difficult to understand SQL.

Writing code generally either pursues readability and maintainability, or pursues the running speed of the program

1.5.1 Single row subqueries

Single-row subquery: A subquery that returns one row of records

student table:

select * from student;
+----+----------+------+
| id | class_id | name |
+----+----------+------+
|  1 |        1 | 张三 |
|  2 |        1 | 李四 |
|  3 |        2 | 王五 |
|  4 |        3 | 赵六 |
|  5 |        2 | 王七 |
+----+----------+------+

Now query the classmates of "Zhang San", and query according to class_id

query separately:

//查询出张三的class_id
select class_id from student where name = '张三';
+----------+
| class_id |
+----------+
|        1 |
+----------+
//查询出来的张三的class_id为 1,再查询除了张三以外的class_id 为1的同学
select * from student where class_id = 1 and name != '张三';
+----+----------+------+
| id | class_id | name |
+----+----------+------+
|  2 |        1 | 李四 |
+----+----------+------+

Single row subquery:

select * from student where 
class_id = ( select class_id from student where name = '张三') 
and name != '张三';
+----+----------+------+
| id | class_id | name |
+----+----------+------+
|  2 |        1 | 李四 |
+----+----------+------+

1.5.2 Multi-row subqueries

Multi-row subquery: A subquery that returns multiple rows of records

scoretable table:

select * from scoretable;
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|    70 |          1 |         1 |
|    96 |          1 |         2 |
|    97 |          1 |         3 |
|    80 |          2 |         1 |
|    92 |          2 |         2 |
|    86 |          2 |         3 |
|    91 |          3 |         1 |
|    76 |          3 |         2 |
|    77 |          3 |         3 |
+-------+------------+-----------+

course table:

select * from course;
+----+------+
| id | name |
+----+------+
|  1 | 语文 |
|  2 | 数学 |
|  3 | 英语 |
+----+------+

Query the score information of each student's "Chinese" and "English" courses

General query:

//首先查询出语文和英语成绩对应的id
select id from course where name = '语文' or name = '英语';
+----+
| id |
+----+
|  1 |
|  3 |
+----+
//再根据查询出来的语文英语对应的id,在 scoretable表中查询
select * from scoretable where course_id = 1 or course_id = 3;
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|    70 |          1 |         1 |
|    97 |          1 |         3 |
|    80 |          2 |         1 |
|    86 |          2 |         3 |
|    91 |          3 |         1 |
|    77 |          3 |         3 |
+-------+------------+-----------+

Multiline subquery:

select * from scoretable where course_id 
in(select id from course where name = '语文' or name = '英语');
+-------+------------+-----------+
| score | student_id | course_id |
+-------+------------+-----------+
|    70 |          1 |         1 |
|    97 |          1 |         3 |
|    80 |          2 |         1 |
|    86 |          2 |         3 |
|    91 |          3 |         1 |
|    77 |          3 |         3 |
+-------+------------+-----------+

1.5.3 Combined queries

Combined query: it is to combine two query result sets into one

In practical applications, in order to combine the execution results of multiple queries, the set operators union and union all can be used. When using UNION and UNION ALL, the fields in the result sets of previous and subsequent queries need to be consistent

  • union operator

The union operator is used to obtain the union of two result sets. When using this operator, duplicate rows in the result set will be automatically removed.

course table:

select * from course;
+----+------+
| id | name |
+----+------+
|  1 | 语文 |
|  2 | 数学 |
|  3 | 英语 |
|  6 | 化学 |
|  7 | 物理 |
+----+------+

Now query the course information whose id is less than or equal to 2 or whose name is "English"

select * from course where id <= 2 union select * from course where name = '英语';
+----+------+
| id | name |
+----+------+
|  1 | 语文 |
|  2 | 数学 |
|  3 | 英语 |
+----+------+

Seeing this, you may have a question. It can be achieved with or, why use union?

Answer: The or query can only come from the same table. If the union query can come from different tables, the result columns to be queried can only be matched. The match is the same type of column, the same column name, and the name of the column. Same

  • union all operator

The union all operator is used to obtain the union of two result sets. When using this operator, duplicate rows in the result set will not be removed

select * from course where id < 3 union all select * from course where name = '数学';
+----+------+
| id | name |
+----+------+
|  1 | 语文 |
|  2 | 数学 |
|  2 | 数学 |
+----+------+

Guess you like

Origin blog.csdn.net/m0_66488562/article/details/129435287