MySQL - multi-table query

Multi-table query, also called associative query, refers to two or more tables to complete the query operation together.

  • If a field that exists in multiple tables appears in the query statement, you must indicate the table where the field is located.
    • SELECT tb_a.id, tb_b.id FROM tb_a,tb_b WHERE tb_a.id=tb_b.id;
  • Tables can be aliased, and table aliases can be used in SELECT and WHERE
    • SELECT t1.id, t2.id FROM tb_a as t1,tb_b as t2 WHERE t1.id=t2.id;
  • If an alias is given to the table, once the table name is used in SELECT or WHERE, the alias of the table must be used instead of the original name of the table.
  • If there are n tables to implement multi-table queries, at least n-1 join conditions are required

1. Multi-table query example

New table:

Old street cat.

SELECT e.employee_id as '员工id',
       e.last_name as '员工名称',
       d.department_name as '员工所在部门',
       l.city as '部门所在城市'
FROM employees e, departments d, locations l
WHERE e.department_id=d.department_id
    AND d.location_id=l.location_id;

result:

employee id employee name employee's department Department City
200 Whalen Administration Seattle
201 Hartstein Marketing Toronto
202 Fay Marketing Toronto
114 Raphaely Purchasing Seattle
115 Khoo Purchasing Seattle

2. Multi-table query classification

2.1 Equal/non-equivalent connection

2.1.1 Equivalent join

Old street cat.
SELECT employees.employee_id as '员工id',
       employees.last_name as '员工名称',
       employees.department_id as '部门id',
       departments.department_id as '部门id',
       departments.department_name as '部门名称',
       departments.location_id as '位置id'
FROM employees, departments
WHERE employees.department_id = departments.department_id;
employee id employee name department id department id Department name location id
200 Whalen 10 10 Administration 1700
201 Hartstein 20 20 Marketing 1800
202 Fay 20 20 Marketing 1800
114 Raphaely 30 30 Purchasing 1700

2.1.2 Non-equivalent connection

SELECT e.last_name as '员工名称',
       e.salary as '员工薪资',
       j.grade_level as '员工级别'
FROM employees e, job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
-- 或者
WHERE e.salary >= j.lowest_sal AND e.salary <= j.highest_sal;
employee name employee salary employee level
King 24000 E
Kochhar 17000 E
Rooster 17000 E
Hunold 9000 C
Ernst 6000 C
Austin 4800 B

2.2 Natural/Unnatural Connections

SELECT emp.employee_id as '员工id', 
       emp.last_name as '员工名称', 
       mgr.employee_id as '管理者id', 
       mgr.last_name as '管理者名称'
FROM employees emp, employees mgr
WHERE emp.manager_id = mgr.employee_id;
或者
SELECT CONCAT(worker.last_name ,' works for ' , manager.last_name)
FROM employees worker, employees manager
WHERE worker.manager_id = manager.employee_id ;

employee id employee name manager id manager name
101 Kochhar 100 King
102 Rooster 100 King
103 Hunold 102 Rooster
104 Ernst 103 Hunold
105 Austin 103 Hunold
106 Pataballa 103 Hunold

2.3 Internal/External Connections

  • Inner join: Merge the rows of two or more tables with the same column, and the result set does not contain rows that do not match one table with another
  • Outer join: During the join process of two tables, in addition to returning the rows that meet the join conditions **, it also returns the rows that do not meet the conditions in the left (or right) table. This connection is called a left (or right) outer join. **When there is no matching row, the corresponding column in the result table is empty (NULL).
  • If it is a left outer join, the table on the left in the join condition is also called the main table , and the table on the right is called the slave table .
  • If it is a right outer join, the table on the right in the join condition is also called the main table , and the table on the left is called the slave table .

2.3.1 Inner joins

SELECT e.employee_id, d.department_id, l.city
FROM employees e
    INNER JOIN departments d
        ON e.department_id = d.department_id
    INNER JOIN locations l
        ON d.location_id = l.location_id;
        
-- 返回 employees_id和department_id都不为NULL的数据

2.3.2 Outer joins

-- 左外连接
SELECT e.employee_id, d.department_id
FROM employees e
    LEFT OUTER JOIN departments d
        ON e.department_id = d.department_id;
        
-- 右外连接

SELECT e.employee_id, d.department_id
FROM employees e
    RIGHT OUTER JOIN departments d
        ON e.department_id = d.department_id;

3. The use of UNION

3.1 Combine query results

Using the UNION keyword, multiple SELECT statements can be given and their results combined into a single result set. When merging, the number of columns and data types corresponding to the two tables must be the same and correspond to each other. Use the UNION or UNION ALL keyword to separate the SELECT statements.
Grammar format:

SELECT column,... FROM table1
UNION [ALL]
SELECT column,... FROM table2

3.1.1 UNION operator

The UNION operator returns the union of the result sets of two queries, removing duplicate records.
Old street cat.

3.1.2 UNION ALL operator

The UNION ALL operator returns the union of the result sets of two queries. For the duplicate parts of the two result sets, do not deduplicate.

Old street cat.
select 'newMember' as "memberType", 
    count(distinct full_union_id) as "memberCount" 
from XXX.XXX  
where XX_id = cast(66666666 as varchar) 
    and XX_time >= '2021-06-16 00:00:00' 
    and XX_time <= '2022-06-16 00:00:00' 

union all

select 'oldMember' as "memberType", 
    count(distinct full_union_id) as "memberCount" 
from XXX.XXX  
where XX_id = cast(66666666 as varchar) 
    and XX_time <'2021-06-16 00:00:00' 
memberType memberCount
oldMember 2,666,888
newMember 1,888,666

Note: The resources required to execute the UNION ALL statement are less than the UNION statement. If you clearly know that there is no duplicate data in the result data after merging data, or you do not need to remove duplicate data, try to use the UNION ALL statement to improve the efficiency of data query.

4. 7 JOIN operations

Old street cat.

Middle image: inner join

SELECT employee_id, last_name, department_name
FROM employees e
    JOIN departments d
        ON e.department_id = d.department_id;

Above Left: Left Outer Join

SELECT employee_id, last_name, department_name
FROM employees e
    LEFT JOIN departments d
        ON e.department_id = d.department_id;

Top right: right outer join

SELECT employee_id,last_name,department_name
FROM employees e
    RIGHT JOIN departments d
        ON e.department_id = d.department_id;

middle left

SELECT employee_id, last_name, department_name
FROM employees e
    LEFT JOIN departments d
        ON e.department_id = d.department_id
WHERE d.department_id IS NULL;

middle right

SELECT employee_id, last_name, department_name
FROM employees e
    RIGHT JOIN departments d
        ON e.department_id = d.department_id
WHERE e.department_id IS NULL;

Bottom Left Picture: Middle Left Picture + Top Right Picture

SELECT employee_id,last_name,department_name
FROM employees e
    LEFT JOIN departments d
        ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL #没有去重操作,效率高
SELECT employee_id,last_name,department_name
FROM employees e
    RIGHT JOIN departments d
        ON e.department_id = d.department_id;

Bottom right image: middle left image + middle right image

SELECT employee_id,last_name,department_name
FROM employees e
    LEFT JOIN departments d
        ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL
SELECT employee_id,last_name,department_name
FROM employees e
    RIGHT JOIN departments d
        ON e.department_id = d.department_id
WHERE e.department_id IS NULL

5. join multiple tables

SELECT B.id, A.sid, C.c_type, C.c_name, D.sku_id
FROM db_name.table_name_a A
	RIGHT JOIN db_name.table_name_b B ON A.id = B.id
    RIGHT JOIN db_name.table_name_c C ON  B.channel_id  = C.channel_id
    RIGHT JOIN db_name.table_name_d D ON A.id = D.oid
WHERE A.code = 16
    AND A.order_status != 4
    AND A.create_time > '2023-03-08 21:00:00'
    AND A.tid = '1234567890'
ORDER BY A.create_time DESC 
LIMIT 200;

NOTE:

We want to 控制连接表的数量. Multi-table joins are equivalent to nested for loops, which consume a lot of resources and seriously degrade the performance of SQL queries, so do not connect unnecessary tables. In many DBMSs, there is also a limit on the maximum number of joined tables.

[Mandatory] Joining is prohibited for more than three tables. The data types of the fields that need to be joined must be absolutely consistent; when multi-table association queries, ensure that the associated fields need to have indexes.

Note: Even if you join two tables, you should pay attention to table indexes and SQL performance.

Source: Alibaba "Java Development Manual"

Guess you like

Origin blog.csdn.net/weixin_44988085/article/details/129448438