MySQL - multi-table join query

1. (Left, right and full) connection concept

Inner join: Assume that tables A and B are connected. Using inner join, all records that can match between tables A and B can be queried. There is no difference between the main payment and the main payment between the two tables A and B. The two tables are equal.


关键字:inner join on
语句:select * from a_table a inner join b_table b on a.a_id = b.b_id;

Description: Combine the records in the two tables and return the records with matching associated fields, that is, return the intersection (shaded) part of the two tables.

Left join (left outer join, means the table on the left is the main table): Assume that tables A and B are connected, and using outer joins, there is a main table and a subsidiary table in the two tables A and B. They mainly query the data in the main table and also query the subsidiary table. When the data in the secondary table does not match the data in the main table, the secondary table automatically simulates NULL to match it. The main features of outer joins: All data in the main table can be queried unconditionally.

关键字:left join on / left outer join on
语句:select * from a_table a left join b_table b on a.a_id = b.b_id;

Explanation: left join is the abbreviation of left outer join, which is called leftouter join, which is one of the outer joins.
For left (outer) join, all the records in the left table (a_table) will be displayed, while the right table (b_table) will only display records that meet the search conditions. Any insufficient records in the right table are NULL.

right join (right outer join, means the table on the right is the main table)


Keywords: right join on / right outer join on
Statement: select * from a_table a right outer join b_table b on a.a_id = b.b_id;
Note: right join is the abbreviation of right outer join. The full name is right outer join, which is a kind of outer join.
Contrary to left (outer) join, right (outer) join, the left table (a_table) will only display records that meet the search conditions, while all records in the right table (b_table) will be displayed. Any insufficient records in the left table are NULL.

Full connection (full external connection)MySQL currently does not support this method, and other methods can be used instead.


Full outer join: There are no restrictions on the left table and the right table, all records are displayed, and the missing parts of the two tables are filled with null, that is:
Left outer join = left table All records + associated results; right outer join = all records in the right table + associated results

To sum up:

  • Inner join: Only matching rows in the two tables are returned, that is, rows with equal join fields in the two tables.
  • Full join: Returns all rows in both tables, regardless of whether there are matching rows. If there are no matching rows in a table, the corresponding portion of the table in the result set will be filled with NULL.

2. Join table query SQL example

Question: Based on the following three tables, find the student with the highest total score.

-- create
CREATE TABLE course(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE student (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE score(
id INTEGER PRIMARY KEY,
course_id INTEGER NOT NULL,
student_id INTEGER NOT NULL,
score INTEGER NOT NULL
);

INSERT INTO course VALUES(1, "语文"), (2, "数学"), (3, "外语");
INSERT INTO student VALUES(1, "小张"), (2, "小王"), (3, "小马");
INSERT INTO score VALUES(1, 1, 1, 80), (2, 2, 1, 90), (3, 3, 1, 70);
INSERT INTO score VALUES(4, 1, 2, 70), (5, 2, 2, 90), (6, 3, 2, 80);
INSERT INTO score VALUES(7, 1, 3, 80), (8, 2, 3, 60), (9, 3, 3, 70);

SELECT *FROM course;
SELECT *FROM student;
SELECT *FROM score;

       ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​?

①. Find the student with the highest total score in all subjects

SELECT s.name, t.total_score 
FROM student s 
RIGHT JOIN 
    (SELECT student_id, SUM(score) AS total_score 
    FROM score 
    GROUP BY student_id 
    HAVING SUM(score) = (
        SELECT SUM(score) 
        FROM score 
        GROUP BY student_id 
        ORDER BY SUM(score) DESC 
        LIMIT 1)
     ) t ON s.id = t.student_id;

The specific SQL is explained as follows:

The purpose of this query is to find the student with the highest overall score and return the student's name and overall score.

  1. Subquery t: First, we execute a subquery to calculate the total grade of each student.

    The subquery obtains each student's student ID () and the corresponding grade sum (). Use to group grades to calculate each student's overall grade. Then, use the line to filter out the students with the highest overall score, ensuring that only students whose total score equals the highest total score among all students are selected. scorestudent_idSUM(score) AS total_scoreGROUP BY student_idHAVING SUM(score) = (SELECT SUM(score) FROM score GROUP BY student_id ORDER BY SUM(score) DESC LIMIT 1)

  2. Main query: In the main query, we use RIGHT JOIN to associate the student table (student) with the subquery t stand up. In this way, we can get the students with the highest total scores and their total scores. Use ON s.id = t.student_id to establish association conditions to ensure that student IDs match.

  3. Result filtering: In the final results, we selected the student's name (s.name) and the corresponding total grade (t.total_score).

②. Find the student with the highest total score in a single subject

SELECT s.name, c.name , s2.max_score FROM score s1
RIGHT JOIN 
    (SELECT MAX(score) max_score, course_id 
    FROM score 
    GROUP BY course_id) s2
ON s1.course_id = s2.course_id AND s1.score = s2.max_score
LEFT JOIN course c ON c.id = s1.course_id
LEFT JOIN student s ON s1.student_id = s.id

The specific SQL is explained as follows:

  • SELECT s.name, c.name AS course_name, s2.max_score: This part defines the columns to be selected. s.name represents the name of the student, c.name AS course_name represents the name of the course (use an alias course_name), s2.max_score Indicates the highest score.
  • FROM score s1: This means querying data from the score table and creating an alias s1 for it.
  • (SELECT MAX(score) max_score, course_id FROM score GROUP BY course_id) s2: This is a subquery that calculates the highest score for each course and stores the result in s2 . It selects the highest score for each course (using the alias max_score) and the course ID.

  • RIGHT JOIN: This is a right join, connecting s1 and s2 . It matches based on course ID and highest score.
  • ON s1.course_id = s2.course_id AND s1.score = s2.max_score: This is the connection condition, used to connect s1 and s2 so that the course ID and the highest score match.
  • JOIN student s ON s1.student_id = s.id: This is an inner join that connects the s1 and student tables. It is based on student ID matching (which shows the student's name).
  • LEFT JOIN course c ON c.id = s1.course_id: This is a left join that connects the s1 and course tables. It is based on course ID matching (which can show the name of the course).
  • The final query results will contain the student's name, course title, and highest score.

        If the original LEFT JOIN  connection operation is changed to RIGHT JOIN, the right table (i.e. subquery s2), while no matching records in the left table (i.e. score s1) in the right table will be included as NULL values. Specifically, a right join (RIGHT JOIN) will return records in the right table that meet the join conditions, and records in the left table that do not meet the join conditions or have no matching records will be included as NULL values.

        In this case, sinces2 is a subquery that calculates the highest score for each course and only contains the information with the highest score, so useRIGHT JOIN may not give the expected results. Because the number of records in the right table is less and the number of records in the left table is more.

        If we want to get all the student names and the highest scores for the corresponding courses and match them with the course names, then using LEFT JOIN is a more common and appropriate choice.

Guess you like

Origin blog.csdn.net/weixin_49171365/article/details/129913263